提高app的响应能力-减少耗时操作

201 阅读2分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

提高app的响应能力-减少耗时操作

在安卓中有两个很重要的原则,第一个是不能在主线程中请求网络,第二个是子线程中不能更新界面。这两个规则都是为了让界面可以流畅快速的响应。开发中我们也要符合这两个规则,才能给用户带来更好的使用体验。

UI线程

UI线程也被称作主线程,是用于更新界面用的,下面的类是大多数安卓应用的基石:
四大组件和常用的类

  • Activity
  • Service
  • ContentProvider
  • BroadcastReceiver
  • Fragment 这些类会给出一些默认的回调接口,这些接口都来自于主线程,比如Activity中的onCreate、Service中的onStartCommand。

在Activity中5秒内无法响应触摸事件或者键盘事件,在广播中10秒内没有处理完成、在Service中前台服务20秒没有响应,就会出现应用无响应。

来验证一下
当我们点击时出发这段代码,会出发无响应,现在的手机为了友好的提示,把ANR的弹窗去掉了,现在是直接闪退,错误日志也是ANR。

E/ActivityManager: ANR in com.xx.myapplication

public void Test(View view){
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

那么这些主线程的耗时操作我们应该怎么处理呢? 当然是另开线程处理了,哪些场景下需要开线程呢? 网络处理、读写存储卡、其它耗时的算法等。

推迟初始化

满足一个功能我们可以预先加载,也可以即时加载,当我们内存足够时,我们可以预先加载并存储起来,这样再次加载时就会让用户感受到很快。

拖延加载当然也有它的可取之处,我们常常在OnCreate中进行初始化所有的界面和数据,这样就会导致OnCreate需要较长的时间才能结束,onCreate结束之后,我们才能看到界面的显示。

由于内存分配也需要花费时间,等到真正使用时再进行分配会更好。同样的,当某个对象并不是立即要使用时,退出创建也是个很好的方法。

当然异步加载也是解决办法,

new Thread() {
            public void run() {
                // 1.执行耗时操作
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        // 2.更新UI
                        updateUI();
                    }
                });
            }
        }.start();