1、手机的启动

打开电源-----通过BootLoader将Linux系统拉起-----配置网络、文件等等引导页面 ------Linux启动 init进程-------Zygote进程创建JVM

-----开启SystemServer,打开Binder线程池和SystemServiceManager ------由这些服务开启ActivityManagerService、WindoeManagerService、PackageManagerService、CameraService、SernorService-----AMS启动Launcher(extends Activity)

2、APP的启动流程

当点击手机屏幕上的APP的时候,就执行了Launcher类中的onClick(view)方法,会调用startActivityintent 进程信息)方法,去通知AMS去开启一个进程,每点击一个App都会开启一个进程;此时Zygote进程就会fork出一个主进程,然后startActivity(intent 进程信息)进程信息就保存到了APP进程,该进程是以ActivityThread为入口,在main( )方法中,调用attach启动APP,然后初始化Application,调用Application的onCreate方法----加载XML----到Activity执行onCreate方法,就算是APP已经启动完成,后面显示在手机屏幕上。

3、启动优化

所以对APP的启动优化,就是从Application初始化----加载XML布局文件-----Activity初始化的这个过程中,完善代码。

(1)黑白屏问题

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimarydark</item>
    <item name="colorAccent">@color/coloraccent</item>

在style文件中,添加parent,就是白屏;不添加parent就是黑屏,不管是黑屏还是白屏,都影响用户体验。

可以在Applicaiton中,制造黑白屏现象。

//模拟黑白屏
try {
    Thread.sleep(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

在style的父类中,存在一个WindowBackground属性

<style name="Platform.AppCompat.Light" parent="android:Theme.Holo.Light">
                                  ......
    <!-- Window colors -->
    <item name="android:colorForeground">@color/foreground_material_light</item>
    <item name="android:colorForegroundInverse">@color/foreground_material_dark</item>
    <item name="android:colorBackground">@color/background_material_light</item>
    <item name="android:colorBackgroundCacheHint">@color/abc_background_cache_hint_selector_material_light</item>
    <item name="android:disabledAlpha">@dimen/abc_disabled_alpha_material_light</item>
    <item name="android:backgroundDimAmount">0.6</item>

    //这个地方就是屏幕的背景颜色
    <item name="android:windowBackground">@color/background_material_light</item>

所以在style中,可以设置这个属性值,来作为Windows的背景。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    //在此设置Window的背景为一张图片,在启动时就会显示这张图片
    <item name="android:windowBackground">@drawable/window_bg</item>
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>

但是这种设置的坏处在于,设置了Window的属性之后,在之后的APP中,背景均是该图片。

另一种方法就是做一个属性,在Mainfest文件中配置Activity启动页的属性。

//自定义属性
<style name="AppTheme.Launcher">
    <item name="android:windowBackground">@drawable/window_bg</item>
</style>

在清单文件启动Activity中,配置theme属性

<activity
    android:theme="@style/AppTheme.Launcher1"
    android:name=".view.activity.SplashActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />


        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

最后需要在代码中,设置一下属性,这样只有在启动的时候会设置这个背景图,其他Activity还是自己的背景模式。

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        //设置属性
        setTheme(R.style.AppTheme_Launcher1);

        findViews();
        initAnimation();
        initEvent();
    }

QQ中黑白屏的处理方法

<item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>

(2)启动时间查看

在Android 4.4以上,通过在Logcat中使用Displayed,可以查看Activity的启动时间。

Android AppStartTask启动优化 安卓手机启动优化应用_子线程


(3)代码执行时间

@Override
    public void onCreate() {
        super.onCreate();
        //分析结果
        File file = new File(Environment.getExternalStorageDirectory(),"appl.trace");
        Log.e("TAG","file==="+file.getAbsolutePath());

        //分析结果保存
        Debug.startMethodTracing(file.getAbsolutePath());

        mContext = getApplicationContext();
        mainThread = Thread.currentThread();
        mainLooper = getMainLooper();
        handler = new Handler();

        //模拟黑白屏
//        try {
//            Thread.sleep(3000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        NetworkApi.init(new NetworkRequiredInfo());

        //结束
        Debug.stopMethodTracing();
    }

通过代码在Application中首尾监测,生成trace文件,就可以放在Android Studio中,通过Profiler工具查看运行的时间。

cmd命令行:adb pull trace文件的路径

Android AppStartTask启动优化 安卓手机启动优化应用_子线程_02


因为初始化的内容比较少,所以有用的信息也比较少。

Android AppStartTask启动优化 安卓手机启动优化应用_android_03

点在某个方法条上,就可以看到该方法执行的时间。

Android AppStartTask启动优化 安卓手机启动优化应用_android_04


在项目开发的过程中,就需要根据方法耗时,来优化耗时长的部分。

Android AppStartTask启动优化 安卓手机启动优化应用_android_05


4、启动时间优化

(1)开线程减少初始化时间

new Thread(new Runnable{
    //初始化操作

}).start();

使用这样方式需要注意的点就是:

-----API中不能创建Handler(子线程中不能创建Handler,因为没有Looper对象)

-----不能有UI操作

-----对异步要求不高:比如说我在Application初始化的时候,开启了子线程,那么这个子线程的初始化时间比较久,但是这个时候,Application早早初始化完成,已经开始Activity的onCreate( )初始化,此时正好需要子线程中初始化的部分,但是还没有初始化完成,这个时候获取API失败,就会报NPE异常。

(2)懒加载

把不需要立刻初始化的部分放到后续代码中,在使用到的时候再初始化。