网站建设费用计算依据,中国芯片制造最新消息,网络建设的重要性,做旅行社网站的App 启动流程
1. 点击桌面 App 图标#xff0c;Launcher 进程采用 Binder IPC 向 system_server 进程发起 startActivity 请求 #xff1b;
2. system_server 进程接收到请求后#xff0c;向 zygote 进程发送创建进程的请求#xff1b;
3. zygote 进程 fork 出新的子进程…App 启动流程
1. 点击桌面 App 图标Launcher 进程采用 Binder IPC 向 system_server 进程发起 startActivity 请求
2. system_server 进程接收到请求后向 zygote 进程发送创建进程的请求
3. zygote 进程 fork 出新的子进程即 App 进程
4. App 进程通过 Binder IPC 向 system_server 进程发起 attachApplication 请求
5. system_server 进程在收到请求后进行一系列准备工作再通过 binder IPC 向 App 进程发送 scheduleLaunchActivity 请求
6. App 进程的 binder 线程ApplicationThread在收到请求后通过 handler 向主线程发送 LAUNCH_ACTIVITY 消息
7. 主线程收到 Message 后通过反射机制创建目标 Activity并回调 Activity.onCreate() 等方法
8. 到此App 便正式启动开始进入 Activity 生命周期执行完 onCreate/onStart/onResume 方法UI 渲染结束后便可以看到 App 的主界面。 App 启动状态
应用有三种启动状态每种状态都会影响应用向用户显示所需的时间冷启动、温启动、热启动
1. 冷启动
冷启动是指应用从开头开始启动系统进程在冷启动后才创建应用进程。发生冷启动的情况包括应用自设备启动后或系统终止应用后首次启动。
2. 热启动
在热启动中系统的所有工作就是将 Activity 带到前台。只要应用的所有 Activity 仍驻留在内存中应用就不必重复执行对象初始化、布局加载和绘制。
3. 温启动
温启动包含了在冷启动期间发生的部分操作同时它的开销要比热启动高。有许多潜在状态可视为温启动。例如 用户在退出应用后又重新启动应用。进程可能未被销毁继续运行但应用需要执行 onCreate() 从头开始重新创建 Activity。 系统将应用从内存中释放然后用户又重新启动它。进程和 Activity 需要重启但传递到 onCreate() 的已保存的实例 savedInstanceState 对于完成此任务有一定助益。
冷启动耗时统计
在性能测试中存在启功时间 2-5-8 原则 当用户能够在 2s 以内得到响应时会感觉系统的响应很快 当用户在 2-5s 之间得到响应时会感觉系统的响应速度还可以 当用户在 5-8s 之间得到响应会感觉系统的响应速度很慢但是还可以接受 当用户在超过 8s 后仍无法得到响应会感觉系统糟透了或者认为系统已经失去响应。
而 Google 也提出一项计划Android Vitals。该计划旨在改善 Android 设备的稳定性和性能。当选择启用了该计划的用户运行您的应用时其 Android 设备会记录各种指标包括应用稳定性、应用启动时间、电池使用情况、呈现时间和权限遭拒等方面的数据。Google Play 会汇报这些数据并将其显示在 Android Vitals 信息中心内。
当应用启动时间过长时Android Vitals 可以通过 Play 管理中心提醒您从而帮助提升应用性能。Android Vitals 在您的应用出现以下情况时将启动时间视为过长 冷启动用了 5s 或者更长时间。 温启动用了 2s 或者更长时间。 热启动用了 1.5s 或者更长时间。
实际上不同的应用因为启动时需要初始化的数据不同启动时间自然也会不同相同的应用也会因为在不同的设备因为设备性能影响启动速度不同。所以实际上启动时间并没有绝对统一的标准我们之所以需要进行启动耗时的统计可能在于产品对我们应用启动时间提出具体的要求。
CPU Profile
如果发现显示时间比希望的时间长则可以继续尝试识别启动过程中的瓶颈。查找瓶颈的一个好方法是使用 Android Studio CPU 性能解剖器。
要在应用启动过程中自动开始记录 CPU 活动请执行以下操作
步骤1Run -- Edit Configurations 步骤2在 Profiling 标签中勾选 Start recording CPU on startup 旁边的复选框。 步骤3从菜单中选择 CPU 记录配置。 Java/Kotlin Method Sample(legacy)
对 java 方法采用在应用的 Java 代码执行期间频繁捕获应用的调用堆栈。分析器会比较捕获的数据集以推导与应用的 Java 代码执行有关的时间或资源使用信息。如果应用在捕获调用堆栈后进入一个方法并在下次捕获前退出该方法分析器将不会记录该方法调用。如果您想要跟踪生命周期如此短的方法应使用检测跟踪。 Java/Kotlin Method Trace
跟踪 Java 方法在运行时检测应用以在每个方法调用开始和结束时记录一个时间戳。系统会收集并比较这些时间戳以生成方法跟踪数据包括时间信息和 CPU 使用率。 System Trace
跟踪系统调用捕获非常详实的细节以便您检查资源的交互情况。您可以检查线程状态的确切时间和持续时间、直观地查看所有内核的 CPU 瓶颈在何处并添加要分析的自定义跟踪事件。要使用此配置您必须将应用部署导搭载 Android 7.0API 级别24或更高版本的设备上。
此跟踪配置在 systrace 的基础上构建而成。您可以使用 systrace 命令行使用程序指定除 CPU Profiler 提供的选项之外的其他选项。systrace 提供的其他系统级数据可以帮助您检查原生系统进程并排查丢帧或帧延迟问题。
步骤4点击 Apply
步骤5依次选择 Run -- Profile将您的应用部署导搭载 Android 8.0(API 级别 26) 或更高版本的设备上。 点击 Stop结束跟踪后显示 Call Chart
以图形来呈现方法跟踪数据或函数跟踪数据其中调用的时间段和时间在横轴上表示而其被调用方则在纵轴上显示。对系统 API 的调用显示为橙色对自己写的方法的调用显示为绿色对第三方 API包括 Java 语言 API的调用显示为蓝色。 如上图自定义 Application 的 onCreate 调用了 Thread.sleep 耗时为 3s。
Call Chart 已经比原始数据可读性高很多但它仍然不方便发现那些运行时间很长的代码这时我们便 需要使用 Flame Chart。
Flame Chart
提供一个倒置的调用图表用来汇总完全相同的调用堆栈。也就是说将具有相同调用、顺序完全相同的方法或函数收集起来并在火焰图(Flame Chart)中将它们表示为一个较长的横条。
横轴显示的是百分比数值。由于忽略了时间线信息Flame Chart 可以暂时每次调用消耗时间占用整个记录时长的百分比。同时纵轴也被对调了在顶部展示的是被调用者底部展示的是调用者。此时的图表看起来越往上越窄就好像火焰一样因此得名火焰图。 Top Down Tree
如果我们需要更精确的时间信息就需要使用 Top Down Tree。Top Down Tree 显示一个调用列表在该列表中展开方法或函数节点会显示它调用了的方法节点。 对于每个节点三个时间信息 Self Time --运行自己的代码所消耗的时间 Children Time -- 调用其他方法的时间 Total Time -- 前面两者时间之和。
Bottom Up Tree
方便地找到某个方法的调用栈。在该列表中展开方法或函数节点会显示那个方法调用了自己。 布局优化
通过工具可以定位到耗时代码然后查看是否可以进行优化。对于 App 启动来说启动耗时包括 Android 系统启动 App 进程加上 APP 启动界面的耗时时长我们可做的优化是 APP 启动界面的耗时也就是说从 Application 的构建到主界面的 onWindowFocusChanged 的这一段时间。
因此在这段时间内我们的代码需要尽量避免耗时操作检查的方法包括主线程I/O第三方库初始化或程序需要使用的数据等初始化改为异步加载/懒加载减少布局复杂度与嵌套层级Multidex(5.0以上无需考虑)等。
加载布局文件也是一个耗时操作。对于布局的优化嵌套的层级不要太深控件不要太多
使用 AsyncLayoutInflater 对布局进行异步加载 StrictMode 严苛模式
希望在开发阶段开启在发布阶段关闭。
StrictMode 是一个开发人员工具它可以检测出我们可能无意中做的事情并用它们提醒我们注意以便我们能够修复它们。StrictMode 最常用于捕获应用程序主线程上的意外磁盘或网络访问。帮助我们让磁盘和网络操作远离主线程可以使应用程序更加平滑、响应更快。
public class MyApplication extends Application {Overridepublic void onCreate() {if (BuildConfig.DEBUG) {//线程检测策略StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads() //读、写操作.detectDiskWrites().detectNetwork() // or .detectAll() for all detectable problems.penaltyLog().build());//虚拟机检测策略StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects() //Sqlite对象泄露.detectLeakedClosableObjects() //未关闭的Closable对象泄露.penaltyLog() //违规打印日志.penaltyDeath() //违规崩溃.build());}
}
启动优化的优化点 合理的使用异步初始化、延迟初始化、懒加载机制。 启动过程避免耗时操作如数据库、I/O 操作等不要放在主线程。 类加载优化提前异步执行类加载 合理使用 IdleHandler 进行延迟初始化 简化布局