大家好,又见面了,我是你们的朋友全栈君。
从一个页面跳转到另外一个页面,这在 Android 中是很常见的操作;有的页面跳转是瞬间打开,有的是会微微钝一下才打开;或者在页面里弹出一个 Dialog 弹框,明明已经调用完了 show()方法,但弹框没马上弹出来,延迟了一百多毫秒才显示出来,这样给人的体验就很不好了。为什么会出现这种情况呢?页面跳转迟钝和弹框的展示延迟的原因都一样,基本分为两大类。
第一类就是看看是否在UI线程左耗时操作,这个经常是数据方面的问题,比如说要从数据库里面查询数据,或者说对数据做了一些复杂逻辑的操作,例如要对集合中的数据,根据bean的某些属性做一些排序、合并等的操作,由或者需要三方sdk提供数据,结果他们提供数据的方法耗时了等等。针对上述情况,我们可以开启一个子线程,来处理这些数据,数据处理工作完成后,再通过 Handler 来接收数据并刷新UI界面,这样就不至于因为数据的原因而导致UI的卡顿了。
上述耗时操作如果是在 onCreate() 或 onResume() 中,必然会导致 Activity 的跳转速度降低。ActivityThread 中已经描述了 Activity 的生命周期,通过它我们知道 UI 是在 Activity的 onResume() 之后才会绘制及显示出来,那么问题就来了,如果在 onCreate() 或 onResume() 中耗时较多,那么 Activity 的跳转速度肯定就慢了;同理,如果弹框的构造方法或 onCreate() 也耗时较多,那么弹框的展示速度也会被拖慢。
第二类就是布局,简单的xml布局,很快就能被转换为UI,但复杂的布局,比如层级比较深的,项目中就会有七八层深的布局,一个页面的 view 加起来有50个,从 Xml 中获取view的节点并转为 FrameLayout、ImageView、TextView 等,是通过反射创建的,本身效率就比较低,再加上 findViewById() ,也可以想象到效率。所以针对这一点,我们可以使用 merge 、ViewStub 等,说白了,就是减少层次,延迟加载等。下面就着重说一下。
从减轻层级方法,对于复杂的布局,可以使用约束布局,这个布局很好用,是相对布局的加强版;有些布局可以通过自定义控件来合并,常见的一个线性布局里面有个文本和图片,我们可以通过自定义view来绘制这些,减轻层级;可以直接代码中创建view,但这种不直观,不推荐。
至于延迟加载,这个可操作的空间比较大,系统封装的 ViewStub 就派上了用场。我们可以把同一业务的合并到同一个里面,这样就可以把复杂的xml布局分割成几小块,我们在根布局中可以只保留一个 LinearLayout ,其他的用 ViewStub,这样就相当于 xml 中只有这么一个控件,初始化起来速度就相当可观了。在 Activity 中,我们可以使用
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
initView();
}
});
这个 Runnable 中的 run() 方法,会在布局初始化完毕后,马上执行,这样就可以在 initView() 中执行 ViewStub 的逻辑了。这样做会导致UI山一下,毕竟这相当于是往空白的容器里添加控件,为了提高体验,可以在跟节点 LinearLayout 中添加一个蒙版View,等 ViewStub 中代码执行完毕后,再把这个蒙版给remove掉,这样就没那么突兀了。
在一些app中也看到过蒙版,主要作用就是上面描述的,其次是为了UI美观。以前一个项目中,产品童鞋看这个蒙版比较好看,直接让我们抄过来,至于它背后的产品逻辑,蒙版的作用及出现的动机,完全不管,抄东西也就只能抄个外形,抓不到精髓。深层次的东西,往往是被重重隐藏的,不会轻易被其他公司的人给抄去。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143447.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...