Android App启动流程:
冷启动app:------>Application:attachBaseContext()------>Application:onCreate()----->Activity.onCreate()
App冷启动相关优化点:
1. 生命周期内减少耗时操作:
.Application.attachBaseContext():
MultiDex.install();
在Android 5.0(API 21) 以下会存在65535方法数分包的问题,当dex过大时会导致Application启动慢, ANR或者ClassNotFound等异常。
.Application.onCreate():
onCreate中会进行第三方SDK初始化工作,可以把这些初始化操作放到一个线程中处理,方便管理。
优化方案:
异步初始化:
Thread、AsyncTask、Handler等IntentService
IntentService是继承Service并处理异步请求的一个类。
public class InitializeService extends IntentService {
private static final String ACTION_INIT_WHEN_APP_CREATE = "com.test";
public InitializeService(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {
performInit();
}
}
}
private void performInit() {
//此处进行第三方sdk初始化
LitePal.initialize(this.getApplicationContext());
}
public static void start(Context context) {
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INIT_WHEN_APP_CREATE);
context.startService(intent);
}
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
InitializeService.start(this);
}
}
3、 界面预加载
4、SDK分优先级加载,非必要SDK懒加载实现
.MainActivity:onCreate()
onCreate中尽量不要添加耗时操作,例如设置闪屏的时候,可以放到onResume()中处理。onResume一定处于可见可交互界面,要遵循Activity的生命周期,尽量减少人为延迟阻塞。
2. 避免冷启动:
App启动方式:冷启动、暖启动、热启动。
冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
暖启动:app的所有Activities还常驻在内存中,并没有被杀掉,所做的只是把app从后台提到前台来展示,并不需要重走初始化一系列行为,减少了对象初始化、布局加载等工作。
热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。
优化方案:
在非用户主动kill进程或系统通知kill进程的其他情况下不再主动退出进程。在位于Activity栈底activity中Hook其返回键行为,保证用户点击返回键后不再退出app。
@Override
public void onBackPressed() {
super.onBackPressed();
moveTaskToBack(true);
}
3. WindowBackGround
App图标点击后,会在桌面停顿一会。原因:项目创建时,系统会为launcherActivity默认了一个LightTheme,这样就会导致App点击启动后会白屏一段时间然后展示自己的Activity。
大多数App解决方案:把theme主题换成透明。
<style name="No_Splash_Light" parent="Theme.AppCompat.Light">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
windowBackground最佳解决方案:决方案:
应该由windowBackground此属性作为你的品牌推广页或者logo页,如果你的SplashActivity完全不需要做任何初始化,只是希望有个闪屏页,完全可以由windowBackground来满足。
1.设置自定义带windowBackground的Theme
2. 为你的launcher Activity设置你的启动Theme
3. 在Launch Activity启动后再把主题设置回自己的AppTheme
推荐测试工具
1. Hugo
工程build.gradle:
dependencies {
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
项目build.gradle
apply plugin: 'com.jakewharton.hugo'
使用: 在方法体添加 @DebugLog
@DebugLog
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add(1, 8);
}
@DebugLog
private int add(int a, int b) {
return a + b;
}
输出:
08-25 14:52:43.413 26165-26165/test.xl.com.myapplication V/MainActivity: ⇢ onCreate(savedInstanceState=null)
08-25 14:52:43.490 26165-26165/test.xl.com.myapplication V/MainActivity: ⇢ add(a=1, b=8)
08-25 14:52:43.490 26165-26165/test.xl.com.myapplication V/MainActivity: ⇠ add [0ms] = 9
08-25 14:52:43.490 26165-26165/test.xl.com.myapplication V/MainActivity: ⇠ onCreate [76ms]
2. Stetho
项目build.gradle
dependencies {
compile 'com.facebook.stetho:stetho:1.5.0'
compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
}
初始化Stetho:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(this);
}
}
使用:1. 运行工程,在chrom浏览器中输入:
chrome://inspect
- 点击inspect
例子:查询存储的SP信息
SharedPreferences sp = getSharedPreferences("test", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("name", "xiaoming");
editor.putInt("age", 20);
editor.putString("sex", "男");
editor.commit();
stetho显示结果:
Logger
项目build.grader
compile 'com.orhanobut:logger:2.1.1'
上述内容摘自腾讯Bugly、马伟奇简书。