1、启动方式
1、冷启动
App没有启动过或App进程被killed, 系统中不存在该App进程。需要创建App进程, 加载相关资源, 启动Main Thread, 初始化首屏Activity等。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至首屏Activity完全启动。
2、热启动
热启动意味着你的App进程只是处于后台, 系统只是将其从后台带到前台, 展示给用户。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至activity渲染完毕。
3、温启动
介于冷启动和热启动之间, 一般来说在以下两种情况下发生:
- 用户back退出了App, 然后又启动. App进程可能还在运行, 但是activity需要重建
- 用户退出App后, 系统可能由于内存原因将App杀死, 进程和activity都需要重启
启动优化主要是针对冷启动. 热启动和温启动都相对较快。
2、在哪进行启动优化?
Application的onCreate
把Application中的一些初始化操作放到子线程里(IntentService)首屏Activity的渲染
设置首屏的主题(windowBackground)
3、怎么优化
1、使用Traceview,找到可以优化的点
- 使用adb
-
adb不是内部命令的解决办法?
配置环境变量,重启AndroidStudio
- 使用trace
Debug.startMethodTracing("HaiGo");
...
Debug.stopMethodTracing();
- 使用adb导出到本地
adb pull /sdcard/HaiGo.trace
-
结果
打开DDMS,打开刚刚保存的trace文件,可以看到bugly是比较耗时的
可以看到,未优化之前,有很长时间的白屏,时间很大一部分费在了bugly上
2、优化Application
把Application中的一些初始化操作放到子线程里(IntentService),如下:
public class AppContext extends Application {
private static AppContext app;
public AppContext() {
app = this;
}
public static synchronized AppContext getInstance() {
if (app == null) {
app = new AppContext();
}
return app;
}
@Override
public void onCreate() {
super.onCreate();
// 在自己想要开始调试的地方start
Debug.startMethodTracing("HaiGo");
InitializeService.startActionInitialize(this);
// 在合适的地方stop
Debug.stopMethodTracing();
}
}
public class InitializeService extends IntentService {
private static final String ACTION_INITIALIZE = "com.hqgj.aishang.service.action.InitializeService";
/**
* 必须提供一个无参数的构造函数,并再其内部调用父类有参数的构造函数
*/
public InitializeService() {
super("InitializeService");
}
/**
* Starts this service to perform ACTION_INITIALIZE with the given parameters. If
* the service is already performing a task this action will be queued.
*/
public static void startActionInitialize(Context context) {
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INITIALIZE);
context.startService(intent);
}
/**
* 再子线程中运行
* @param intent
*/
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_INITIALIZE.equals(action)) {
handleActionInitialize();
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionInitialize() {
initImgLoader();
Bugly.init(getApplicationContext(), "11111111", false);
}
private void initImgLoader() {
//显示图片的配置
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_default_img)
.showImageOnLoading(R.drawable.ic_default_img)
.showImageOnFail(R.drawable.ic_default_img)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
/*.displayer(new RoundedBitmapDisplayer(20))*/
.build();
//图片加载器ImageLoader的配置参数
ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.threadPoolSize(5)
.memoryCache(new WeakMemoryCache())
.writeDebugLogs()
.threadPriority(Thread.MIN_PRIORITY)
.build();
ImageLoader.getInstance().init(config);
}
}
可以看到,启动明显快了很多;但因为在渲染首屏的时候花费了一些时间,还是可以一段白屏。。。
3、优化首屏Activity
为首屏页面加上一个windowBackground
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowBackground">@drawable/logo_splash</item>
</style>
<!--@drawable/logo_splash文件-->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 如果item下的 bitmap 没有设置 gravity ,再API 23 以下,会出错! -->
<item
android:drawable="@color/splashBg"
android:gravity="fill" />
<item android:gravity="top">
<bitmap
android:gravity="top"
android:src="@drawable/splash_top" />
</item>
<item
android:bottom="72dp"
android:gravity="bottom|center_horizontal">
<bitmap
android:gravity="bottom"
android:src="@drawable/splash_bottom" />
</item>
</layer-list>
</br>
完成
所以,以后不要在Application中做复杂的初始化操作,为首屏添加一个PlaceHolder
</br>
最后,感谢大神:
Android App优化之提升你的App启动速度之理论基础、Android App优化之提升你的App启动速度之实例挑战