APP性能优化的几种手段

延时加载

    延时加载主要是针对一些非紧急的资源采用的优化方式,比如菜单,可以放在onWindowFocusChanged 中,待页面加载结束后,再加载菜单。另外还有IdleHandler、ViewStub之类的延时处理。

IdleHandler

    IdleHandler,顾名思义,空闲Handler,表示当前MessageQueue中的事情都已经做完了,可以回调这个接口处理这里边定义的事情了,主要处理一些不紧急的事物使用方式如下代码所示:

// 将费时的不紧急的事务放到IdleHandler中执行
    Looper.myLooper().getQueue().addIdleHandler(new MessageQueue.IdleHandler() {
        @Override
        public boolean queueIdle() {
            // 判断当前webView是否存在
            boolean webViewExist = true;
            try {
                String fakeAddress = "120 Main St NewYork,NY";
                // Try whether webView can be used or not.
                WebView.findAddress(fakeAddress);
            } catch (Exception e) {
                webViewExist = false;
            }
            ...
            return false;
        }
    });

    在使用IdleHandler时,需要注意它的返回值,返回false,表示执行完回调后就会移除它,返回true,则在下次Message处理完后还会继续回调。

   之前遇到过IdleHandler相关的Bug,在fragment被销毁重建后,定义在onCreateView中的 IdleHandler回调代码未完全执行,发现原因是其中某个对象未被初始化即对其进行使用,导致崩溃,按照正常的生命周期,onIdleHandler会在onWindowFocusChange之后执行,但某些异常情况下,比如userdebug版本性能很差的时候,onIdleHandler可能会在onWindowFocusChange之前执行,导致某些对象的初始化被延后而出现异常,而从源码实现机制可以看到,IdleHandler会自动捕获Exception,不会弹出崩溃提示框,所以工程师不易察觉,崩溃之后的代码也不会再执行,继而导致其他异常。所以使用IdleHandler时,需尽量保障回调代码的独立性和正确性,以免出现异常而不知。

ViewStub

    ViewStub主要用于View的延时加载,对于一些仅在特定场景下才需要显示的布局,可以采用此种方式。

    以短信首页的空会话布局为例,优化前,它在fragment中的布局如下:

<include
        layout="@layout/list_empty_view"
        android:id="@+id/no_conversations_view"
        android:visibility="gone" />

    改用ViewStub后,布局如下所示:

<ViewStub
        android:id="@+id/no_conversations_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/list_empty_view"/>

    从上改动可以看出,ViewStub本身也是一种页面元素,据官网介绍,它是一个轻量级的View,一个看不见的,不占布局位置,占用资源非常小的控件。如上代码所示,我们给ViewStub指定一个布局,在页面Inflate的时候,ViewStub只会被初始化,不会加载布局,只有当ViewStub被设置为可见或是调用ViewStub.inflate()的时候,ViewStub所指向的布局才会被Inflate和实例化。这样一来,就可以通过使用ViewStub,仅在资源需要使用时进行加载,避免了资源浪费,同时减少渲染时间。

热启动优化    

    热启动定义:在最底层Activity(一般就是应用的主页MainActivity),点击返回按钮;Activity消失后,点击桌面图标或者从最近任务中打开,应用MainActivity重新启动,这次启动属于热启动。

    点击返回按钮,默认会触发Activity的finish操作,但是不会杀掉进程。所以应用热启动时间,可以认为是创建第一个Activity的时间。加快MainActivity的创建和显示,就是热启动优化的核心。

    在优化之前,可以先查看主界面热启动时应用所占内存的变化,rugu点击back和重新打开,应用稳定后内存几乎没变化,那么在用户点击Back按钮时,完全可以保留该Activity,达到快速热启动的目的,优化代码如下:

@Override
public void onBackPressed() {
    if (!moveTaskToBack(true)) {
        super.onBackPressed();
    }
}

    备注:

    1.Android本身的设计,就是允许App自定义Back的行为的,所以,理论上所有类型的App都可以采用该方案优化。

    2.主界面占据内存比较少的应用可以直接添加代码对应代码即可。

    3.对于在首界面占用内存资源比较多的应用,应该检查Activity 和 Fragment 的 destroy 方法,将释放资源的操作移动到 pause 或 stop,然后再检查create方法,将加载资源操作移动到 resume 或 start 。

减少过渡绘制

    打开开发者选项中的“显示过度绘制区域”开关,可以看到各个页面的绘制情况,一般来说,白色、蓝色和绿色是可接受的,如果不是特别复杂的布局,尽量不要出现红色,减少过度绘制主要是通过简化布局,减少层级等方式,去除不必要的背景设置等,视具体页面而定,可去除多余的背景设置,或利用merge标签减少视图节点等,此处不详细展开讲。

清除无用资源

    通过使用Android Studio提供的Lint工具,可以快速的查找出无用资源,包括字符串、布局文件、图片等,通过批量操作,可以做到快速清理无用资源,网上有很多教程,此处不再格外介绍。如果发现Android Studio无法检测出无用资源,可能是Android  Studio的版本问题,可能升级到最新版试试。

猜你喜欢

转载自blog.csdn.net/ZX_XI/article/details/80030979