app启动
开机 ——>BootLoader(引导芯片) ——>Linux kernel(init.rc) ——>init进程 id为1 ——>zygote进程 ——>JVM,SystemServer等
——>Binder线程池、SystemServerManager等其他各种服务 ——>Lancher
启动方式
冷启动 程序从头开始,系统没有为改程序创建进程。一般场景:程序安装后的第一次启动,应用程序被系统完全终止后再打开
热启动 此时程序仍然驻留在内存中,只是被系统从后台带到前台,因此程序可以减少对象初始化,加载布局和渲染的工作。需要注意的是
如果程序的某些内存被系统清除,比如调用了onTrimMemory方法,则需要重新创建这些对象以响应热启动事件
暖启动 它包含热启动和冷启动一系列的操作子集,比热启动的消耗稍微多一些,他与热启动相比最大的区别在于,他必须调用onCreat()开始重新创 建活动,也可以从传递给onCreat()方法中保存的实例状态中 获得某些对象的恢复
冷启动流程:1.加载并启动app,
2.启动后立即为该app显示一个空白页面
3.创建app进程(创建应用程序对象)
4.创建主Activity
5.加载布局,绘制
黑白屏原因:在app的启动流程中,我们已知:在系统启动并加载app时,我们需要耗费相当的时间,即使时间不到1s,用户也会感觉到当点击app图标时,有延迟的现象,为了解决这一问题,Google的做法是在app创建的过程中,先展示一个空白页面,让用户体会到点击图标之后立马会有相应,而这个空白页面的颜色则是在Manifest文件中配置的主题颜色来决定的,现在默认一般都是白色
黑白屏的解决方案
1.修改AppTheme:在应用默认的AppTheme中,设置系统"取消预览(空白窗体),为true,或者设置空白窗体为透明"
<item name="android:windowDisablePreview">true
<item name="android:windowIsTranslucent">true</item>
2. 利用splashActivity,修改theme,自定义theme时,设置windowBackgroud属性(通过layer_list), 利用修改空白页面
代码优化
代码未优化的问题
在构建app的时候,会引用很多的第三方的sdk,而且项目越多,引用的第三方的也越多,有些第三方会要求我们,在application的onCreat里面初始化,所以从application到activity的事件就会被拉长,首个activity的渲染时间就会被拉长
同理,如果我们在activity的oncreat等方法中,执行任务过长的话,也会导致渲染布局的时间被拉长,这样就会导致用户感觉页面迟迟没有被加载出来。
app启动时间检测
adb shell am start-W com.neopt1/.MainActivity
运行时间
thisTime:最后一个activity运行时间
totalTime:一系列activity运行时间
waitTime:总运行时间,包含冷启动运行时间(冷启动时间app无法优化,取决与手机性能和厂商系统)
在application中
public class NeOptApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
File file = new File(Environment.getExternalStorageDirectory(),"app.trace");
Debug.startMethodTracing(file.getAbsolutePath());
// 中间业务逻辑代码
init();// 主线程
test();
// 异步线程的方式来进行处理
// 1:异步线程中使用的api不能创建Handler
// 2:不能有UI操作
// 3:对异步要求不高
// 懒加载
Debug.stopMethodTracing();
}
private void init(){
a();
}
private void a(){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
b();
test();
}
private void b(){
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void test(){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 减少代码执行时间,将执行的代码能放到异步线程
}
在Android studio中定位到项目目录下
adb pull storage/emulated/0/app.trace
生成app.trace文件后,将文件拉取到Android studio中,就可以查看运行时间
优化的方法
// 异步线程的方式来进行处理
// 1:异步线程中使用的api不能创建Handler
// 2:不能有UI操作
// 3:对异步要求不高
// 懒加载
布局渲染流程及原理
XML布局显示至屏幕流程
<Button with="">===>LayoutInflater加载进内存===>CPU进行计算,处理成位图===>CPU将图形将给GPU===>GPU队形进行栅格化===>显示器进行显示
FPS
12fps:画面帧率高于每秒10-12帧,眼睛认为它是连贯的
24fps:有声电影一般每秒24帧
30fps:早期动态电子游戏,一般会在30fps每秒
60fps:手机交互过程中,需要触摸和反馈,需要60帧才会达到不卡顿的效果。
过度绘制 GPU每隔16毫秒画一次,如果CPU传递过来的图形有重复位置,会造成用户只能看到顶层的图形,底层图形被遮盖,虽然用户无法看到顶层图形,但依然会浪费资源,因此被称作过度绘制、
UI优化解决方案
布局中的背景是否需要
是否可以删除多余布局
自定义view是否进行了相应的剪裁
布局是否扁平化,层级不要太深
使用Merge标签排除多余一层ViewGroup容器
使用ViewStub进行布局的懒加载(使用代码优化)
内存优化
Java虚拟机,GC回收,内存抖动/泄露
Java虚拟机 执行流程 编译时环境:Activity.java--java编译器---Activity,class
运行时环境:Activity.class--java虚拟机--内存
Java虚拟机运行时数据区域 方法区 栈内存 本地方法栈 Java堆内存 程序计数器(记录线程运行记录)
Java堆内存 强引用 新建对象为强引用时,垃圾回收器绝对不会回收,宁愿抛出OutOfMemoryError,让程序终止也不会回收
软引用 新建对象为软引用时,当内存不够的时候,回收器就会回收这些对象,如果回收后还是没有足够的内存, 就 会OutOfMemoryError异常。
弱引用 当新建对象为弱引用的时候,垃圾回收器不管当前内存是否足够,都会回收它的内存
虚引用 虚引用和其他引用都不同,如果一个对象仅持有虚引用,在任何时候都可能会被GC回收,只是当他被回收的时候会收到一个 系统通知。
内存泄露/溢出
内存泄露 一个不再被程序使用的对象或变量依旧存活在内存中无法回收;
内存溢出 当程序申请内存时,没有足够的内存供程序使用,比较小的内存泄露并没有太大的影响,但内存泄漏将多时,占用的内存空间较大,程序正常使用的内存就会相应减少
内存抖动 短时间内发生了多次内存分配和释放,主要原因短时间内频繁创建对象,为了应对 这种情况,虚拟机会频繁GC,当GC进行时,其他操作就会被挂起等待GC完成,频繁GC,也就会导致比如Ui绘制时间超过16ms每帧,导致画面卡顿等。
内存分析工具:Mat https://www.eclipse.org/mat/downloads.php
网友评论