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)方法,会调用startActivity
(intent 进程信息
)方法,去通知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的启动时间。
(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文件的路径
因为初始化的内容比较少,所以有用的信息也比较少。
点在某个方法条上,就可以看到该方法执行的时间。
在项目开发的过程中,就需要根据方法耗时,来优化耗时长的部分。
4、启动时间优化
(1)开线程减少初始化时间
new Thread(new Runnable{
//初始化操作
}).start();
使用这样方式需要注意的点就是:
-----API中不能创建Handler(子线程中不能创建Handler,因为没有Looper对象)
-----不能有UI操作
-----对异步要求不高:比如说我在Application初始化的时候,开启了子线程,那么这个子线程的初始化时间比较久,但是这个时候,Application早早初始化完成,已经开始Activity的onCreate( )初始化,此时正好需要子线程中初始化的部分,但是还没有初始化完成,这个时候获取API失败,就会报NPE异常。
(2)懒加载
把不需要立刻初始化的部分放到后续代码中,在使用到的时候再初始化。