综合案例
应用启动(AppStartup)性能优化——使用NoHttp获取应用列表
案例编写:
1、使用的资源如下
2、需要关联的库
compile 'com.yolanda.nohttp:nohttp:1.1.0'
compile 'com.orhanobut:logger:1.15'
compile 'com.android.support:design:24.2.1'
3、初始化NoHttp
Logger.setTag("NoHttp");
Logger.setDebug(true);
NoHttp.initialize(this,newNoHttp.Config()
.setConnectTimeout(30 * 1000)
.setReadTimeout(30 * 1000)
);
问题表现:通常从用户点击到应用完全展示完首页,需要用户等待一段时间。我们如何缩短时间并提高用户体验。
分析:应用在启动的过程中我们的代码能够影响启动速度的地方如下
l Application的onCreate
l 首屏Activity的渲染
步骤:
1. 利用Traceview工具观察启动过程方法耗时情况,重点关注onCreate方法(自定义Application和首页Activity)。问题:Traceview工具如何在应用启动时监控数据?
2. 分析自定义Application耗时操作,判断onCreate方法中的内容(如:第三方的工具是否可以不占用主线程进行初始化)。
3. 查看界面是否存在过渡绘制。
4. 利用Hierarchy Viewer工具查看界面需要优化的点。
5. 启动过程中的白屏优化。
第一步:观察耗时情况
1. 在onCreate开始和结尾打上trace
Debug.startMethodTracing("POApp");
...
Debug.stopMethodTracing();
运行程序, 会在sdcard上生成一个"POApp.trace"的文件.
注意:
① 需要给程序加上写存储的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
②Android6.0以后的模拟器需要为应用打开读写权限
2. 通过adb pull将其导出到本地
adb pull /sdcard/ POApp.trace 存放文件路径
第二步:分析数据
通过DDMS的FileàOpen File
查询结果如下
说明:我们使用Real Time/Call(调用时间和调用次数)进行排序可以得到上图内容
大家可以发现在Application中阻塞主线程干的工作都是NoHttp的初始化工作。为了提高应用的启动速度,我们可以将这个工作放到子线程中完成,通常我们会使用IntentService来处理这个工作。
代码如下:
public class InitServiceextendsIntentService {
public InitService() {
super("init");
}
public static void start(Context context) {
Intent intent = new Intent(context, InitService.class);
context.startService(intent);
}
@Override
protected voidonHandleIntent(@NullableIntent intent) {
Logger.setTag("NoHttp");
Logger.setDebug(true);
NoHttp.initialize(this,newNoHttp.Config()
.setConnectTimeout(30 * 1000)
.setReadTimeout(30 * 1000)
);
}
}
修改完成后,会引发一个问题,及在首页访问网络时(会产生比较严重的问题,一定要注意若是到首页没有完成会不会影响到下边的功能),由于NoHttp的初始化还没有完成会报出如下异常:
如果我们在首页就需要立即访问网络,就需要对初始化进行监控,可以简单的使用一个boolean值,进行判断,当初始化完成后boolean值修改为true。我们在MainActivity中可以使用Handler间隔一段时间就检查一下boolean即可。
第三步:过渡绘制
进入首页后,应用的启动速度限制就集中在首页的界面渲染上了。因此我们开始对界面进行优化处理。
过渡绘制查看结果。
表现还好,我们可以检查一下Item,看看是否可以优化掉一次绘制。
第四步:优化界面布局
Hierarchy Viewer工具派上用场了,我们可以检查一下布局是否合理。
重点观察其中一个条目
优化完成后的结构图
我们先优化掉两个用处不大的LinearLayout,然后在考虑是否可以继续优化掉条目中的LinearLayout。
第五步:Launch screens设置
两种处理方案:
方案一:设置成透明的界面,制造延时启动效果
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
方案二:设置一个背景图
<item name="android:windowBackground">@drawable/splash</item>
<item name="android:windowNoTitle">true</item>
注意:当界面加载完成后需要将背景改成白色。