Android开发Android开发经验谈Android开发

Android性能优化

2018-12-07  本文已影响20人  鸿羽羽羽羽羽

Android性能优化

简介

这篇文章主要打算从几个方面讲解一下怎么去对app进行性能优化。不打算涉及任何概念相关的东西,比如渲染机制等等,因为网上已经够多这方面的了。仅仅从自己的优化过程出发,列出一个能一步步去执行的清单和具体操作办法。

启动速度
查看每个界面的打开速度

在logcat中输入Diaplayed即可查看每个页面的打开时间。当然了,不同配置的手机打开速度肯定是不同的,这个其实没有太大的参考意义,只是知道就行。

image
设置闪屏启动图

一般是在splash页的主题设置

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">     <item name="android:windowBackground"@mipmap/launch</item>   //闪屏页图片     <item name="android:windowFullscreen"true</item>     <item name="android:windowContentOverlay"@null</item> 
</style> 

这样就会先展示一张图片出来,而不是出现白屏的效果,视觉效果优化而已,稍微提升用户体验,但是其实并没有加快启动速度。

还有一种启动图的思路是不用单独的Activity去加载广告和启动页,而是做成SplashFragment直接放到主界面里面,2,3秒之后移除。但是这种方法就没办法解决闪屏白屏的问题。这两种可以酌情选择吧。

application初始化

我们通常会在application里面做一些第三方组件的初始化操作,比如图片加载,数据库等,如果初始化的东西太多,肯定会影响到app的启动。建议将一些在开屏不必须的组件初始化放到子线程去做初始化操作,或者通过IntentService来做。

我自己就是通过IntentService来做的,因为IntentService的特点就是会开启一个工作线程(HandlerThread)来处理耗时操作,并且在完成后会自动停止。

 //初始化的IntentService,和普通的service启动方式并没有太大区别
 Intent intent = new Intent(mContext, InitializeService.class);
 intent.setAction(ACTION_INIT_WHEN_APP_CREATE);
 startService(intent);
 public class InitializeService extends IntentService {
     public InitializeService() {
         super("InitializeService");
     }

     @Override
     protected void onHandleIntent(Intent intent) {
        //初始化操作(你自己定义的操作)
         init();
         if (intent != null) {
             final String action = intent.getAction();
             if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {
                 //这里是个网络请求(你自己定义的请求)
                 performInit();
             }
         }
     }  
 }

我知道其实我就算这么一说,很多小伙伴在操作的时候还是通常会按照原来的习惯去操作。因为现在手机的配置越来越好了,app本身就已经得到了buff加成。但是如果app启动速度实在到了不可忍受的地步,可以参考我上面的做法

布局优化

布局嵌套层级过多。从前有个人说过一句话:没有什么布局是一层嵌套解决不了的,如果有那就两层。所以写着写着经常四五层嵌套就出来了,再加上文字图片的绘制,分分钟。。。

嵌套过多我们可以通过开发者选项里面的调试GPU过渡绘制打开。然后在界面上会显示出不同的颜色块。

布局层级颜色

通常我们可以从这几个角度去优化:

 //采用静态内部类的形式创建Handler,并使用WeakReference引用Activity
 private static class MyHandler extends Handler {
        private final WeakReference<Main2Activity> mActivity;

        public MyHandler(Main2Activity activity) {
            mActivity = new WeakReference<Main2Activity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            Main2Activity activity = mActivity.get();
            if (activity != null) {
                // ...dosomething
            }
        }
    }

//在销毁Activity之后清空handler里面的消息
@Override
  protected void onDestroy() {
    super.onDestroy();
    mHandler.removeCallbacksAndMessages(null);
  }

解决方案:将内部类改为静态内部类,使用弱引用或者软引用的方式,来引用外部类。

2.Context导致的内存泄漏。

一般我们写工具方法的时候会使用单例模式去创建一个对象,在构造器里面要传入一个context,这个context若是ApplicationContext就不会存在内存泄漏,但是如果是其他的context就会导致内存泄漏

public class SingleInstance {

    private Context mContext;
    private static SingleInstance instance;

    private SingleInstance(Context context) {
        //这样写会有内存泄漏
        //this.mContext = context;

        //不管传入什么context,都应该使用ApplicationContext,单例的生命周期和应用的一样长,这样就防止了内存泄漏。
        this.mContext = context.getApplicationContext();
    }

    public static SingleInstance getInstance(Context context) {
        if (instance == null) {
            synchronized (SingleInstance.class) {
                if (instance == null) {
                    instance = new SingleInstance(context);
                }
            }
        }
        return instance;
    }
}

补充关于Context作用域的问题

Context的使用
3.其他可能导致内存泄漏的补充。
上一篇 下一篇

猜你喜欢

热点阅读