Android性能优化分析总结

一,布局优化

主要包括以下几个部分

 1.1,UI渲染机制

要想做好布局优化,首要要了解AndroidUI渲染机制;在Android中,系统是通过VSYNC信号触发对UI渲染,重绘,其间隔是16ms(毫秒);16毫秒的来历就是1000ms中显示60fps(帧)画面的单位时间,即1000/60约等于16毫秒;人眼所感觉的流畅画面是每秒需要显示40到60帧;

例如一次绘制任务需要25毫秒,那么在16毫秒系统VSYNC信号时还没有完成绘制,该帧就会被丢弃,等待下次信号才开始绘制,导致2*16ms 内都是显示同一帧画面,这就是卡顿的原因;

1.2,减少布局层级

布局优化的思想很简单,就是减少布局的层级;能试用LinearLayout和FrameLayout布局,就不使用RelativeLayout布局,因为RelativeLayout的功能比较复杂,它的布局过程需要花费根多的CPU时间;但是如果使用LinearLayout使布局层级变多的话,尽量使用RelativeLayout布局减少层级,如果可以的话;或者使用ConstraintLayout(约束布局)减少层级嵌套;

1.3,使用include 、merge 、ViewStub标签

<include>标签主要作用是:布局重用;

<include layout = "@layout/titlebar">

注意事项:支支持android:layout_开头的属性(android:id属性除外),比如android:layout_width、android:layout_height;而且如果include标签指定了android:layout_*属性,那么android:layout_width、android:layout_height必须存在;

<merge>标签主要作用:和include标签配合使用减少布局的层级;merge的布局取决于父控件是哪个布局,使用merge相当于减少了自身的一层布局,直接采用父include的布局;

<ViewStub>标签主要作用:延迟加载,按需加载布局;是个轻量级的View,且宽高为0;

使用:

<ViewStub
        android:id="@+id/vs"
        android:inflatedId="@+id/panel_import"
        android:layout_width="match_parent"
        android:layout="@layout/bottom_bar"
        android:layout_height="wrap_content" />

其中:vs是ViewStub的id,panel_import是@layout/bottom_bar跟布局的id;

显示ViewStub主要有两种:

第一种是调用ViewStub的setVisibility()方法,mViewStub.setVisibility();

第二种是调用ViewStub的inflate()方法,mViewStub.inflate();

不管使用暗中方式,一旦ViewStub设置为可见或者被inflate,ViewStub就不存在了,取而代之的是被inflate的layout;

如何再隐藏:只能通过第二种方式得到inflate后layout的View实现显示和隐藏,这和陪同的View实现显示和隐藏相同;

btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
              if (mView == null) {
                  mView = mViewStub.inflate();
                  content.setText("隐藏");
              } else {
                  if ("显示".equals(content.getText())) {
                      mView.setVisibility(View.VISIBLE);
                      content.setText("隐藏");
                  } else if ("隐藏".equals(content.getText())) {
                      mView.setVisibility(View.GONE);
                      content.setText("显示");
                 }
             }
         }
});

二,绘制优化

2.1,避免过度绘制

过度绘制检测方法:开发者选项  —>  调试GPU过度绘制  —>  显示过度绘制区域

移除重复的背景色

例如activity使用的theme中一般都有windowBackground,xml布局中的跟布局又设置了background属性,导致背景重复;解决办法很简单移除windowBackground就好;

移除子View多余的背景色

例如父布局中设置了#ff00ff,但是子View也这是了#ff00ff,导致背景色重复;

2.2,View的onDraw方法要避免执行大量的操作,主要体现的两个方面;

一方面onDraw方法中不要创建新的局部变量,因为onDraw方法可能会被平凡的调用,这样就会产生大量的临时的对象;

另一方面,onDraw方法中不要做耗时的任务,也不要执行上万次的循环,不然会造成View绘制过程的不流畅;

三,内存优化

LMK(Low Memory Killer):提前回收优先级比较低的进程所占的资源,以保证一个较好的用户体验。进程优先级列表由 SystemServer 进程维护;由于Android应用的沙箱机制,为每个应用所分配的内存大小是有限度的,内存太低就会触发LMK机制;极大的影响了用户体验,所以要做内存优化;

内存:通常所说的内存是指手机RAM,主要包括:寄存器,栈(Stack),堆(Heap),静态存储区,常量池;

3.1,Bitmap优化

使用适当分辨率和大小的图片,使用图片缓存;对图片进行压缩;

3.2,对常量使用static修饰

3.3,不要把activity赋值给静态变量;

例如在Activity中 public static Context  mContext = this;这样会导致当前Activity不能释放,造成内存泄漏;

3.4,减少使用不必要的成员变量;

3.5,减少不必要的对象;

3.6,尽量不要使用枚举和迭代器;

3.7,File,Receiver,Cursor等对象,注意使用后释放掉;

3.8,使用SurfaceView替代View进行大量,频繁的绘制操作;

3.9,属性动画开启之后,记得在关闭页面的时候停止动画;

四,线程优化

线程优化一般采用线程池替代线程的方法;这样避免程序中存在大量的线程,也避免了创建销毁线程所带来的性能开销;

五,启动速度优化

如果Application.onCreate()方法中初始化的时间太长,导致会有一段时间的黑屏或者白屏;

解决办法:

1,使用透明主题:

<item name="android:windowIsTranslucent">true</item>  Activity.onCreate()之前App不做显示

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item> 
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsTranslucent">true</item> 
    </style>
</resources>

2,替换主题

首先在项目的res —> values —> style中新建一个样式AppTheme.Luncher

<style name="AppTheme.Launcher">
        <item name="android:windowBackground">@mipmap/pop_cart_limit_bg</item>
</style>

接着把这个样式设置到主Activity

<activity android:name="com.xjkj.aidlcreate.MainActivity"
            android:theme="@style/AppTheme.Launcher">
     <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
</activity>

最后在主Activity的onCreate方法中设置原来的主题样式

 protected void onCreate(Bundle savedInstanceState) {
        //替换为原来的主题,在onCreate之前调用
        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}     
发布了95 篇原创文章 · 获赞 58 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/ezconn/article/details/105310260