700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用启用普

【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用启用普

时间:2024-08-02 21:56:38

相关推荐

【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用启用普

文章目录

一、 Launcher 应用 startActivitySafely 方法分析二、 Launcher 中的 startActivity(View v, Intent intent, Object tag) 方法分析三、 Android 应用进程分析

上一篇博客 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用简介 | Launcher 应用源码简介 | Launcher 应用快捷方式图标点击方法分析 ) 分析了 Launcher 应用中 Launcher.java 界面代码 , 并分析了图标点击事件 onClick 方法 , 本篇博客继续分析 Launcher 应用中启动普通 Android 应用的源码 ;

一、 Launcher 应用 startActivitySafely 方法分析

在 Launcher 应用中 , 点击快捷方式图标 , 调用 onClick 方法 , 如果判定点击的图标组件时应用图标 , 会触发调用 startActivitySafely 方法 , 启动该图标对应的 Android 应用 Activity 界面 ;

boolean startActivitySafely(View v, Intent intent, Object tag) {boolean success = false;try {// 启动新的应用success = startActivity(v, intent, tag);} catch (ActivityNotFoundException e) {Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);}return success;}

该段代码在 \packages\apps\Launcher2\src\com\android\launcher2\Launcher.java 界面中定义 , 该界面是 Launcher 应用的主界面 ;

二、 Launcher 中的 startActivity(View v, Intent intent, Object tag) 方法分析

1 . Launcher 中的启动方法 :Launcher 应用中启动 Android 应用 , 调用 startActivity(View v, Intent intent, Object tag) 方法 , 在该方法中 , 启动 Android 应用的启动 Activity ;

3 . 实际启动方法 :在 startActivity(View v, Intent intent, Object tag) 方法中启动 Android 应用的核心方法是 startActivity(intent, opts.toBundle()) 和 startActivity(intent) 启动安卓应用界面 ;

( 该 startActivity(intent) 方法就是我们经常调用的启动界面的方法 )

4 . Intent 来源 :该启动 的 Intent 参数是之前 onClick 方法中从 Launcher 中的图标组件中获取的 Tag 标签 ;

public void onClick(View v) {// 该从 View v 组件中获取的标签 Tag 就是 IntentObject tag = v.getTag();if (tag instanceof ShortcutInfo) {// 获取 Intent 对象 , 可以直接根据该对象启动应用 Activity 界面final Intent intent = ((ShortcutInfo) tag).intent;}}

5 . Launcher 应用中 startActivity(View v, Intent intent, Object tag) 方法源码 :

boolean startActivity(View v, Intent intent, Object tag) {// 设置一个启动标志// 查找当前任务栈中是否有与该 Activity 亲和性相同的任务栈// 如果有将该任务栈移动到前台 , 至于是创建新 Activity 还是复用原来 Activity , 按照该 Activity 的启动模式进行操作// 如果没有亲和性相同任务栈 , 创建任务栈 , 移动到前台intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);try {// Only launch using the new animation if the shortcut has not opted out (this is a// private contract between launcher and may be ignored in the future).boolean useLaunchAnimation = (v != null) &&!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);LauncherApps launcherApps = (LauncherApps)this.getSystemService(Context.LAUNCHER_APPS_SERVICE);if (useLaunchAnimation) {ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,v.getMeasuredWidth(), v.getMeasuredHeight());if (user == null || user.equals(android.os.Process.myUserHandle())) {// Could be launching some bookkeeping activity// 根据 Intent 启动点击图标对应的 Activity 界面startActivity(intent, opts.toBundle());} else {launcherApps.startMainActivity(intent.getComponent(), user,intent.getSourceBounds(),opts.toBundle());}} else {if (user == null || user.equals(android.os.Process.myUserHandle())) {// 真实启动应用的方法// 根据 Intent 启动点击图标对应的 Activity 界面startActivity(intent);} else {launcherApps.startMainActivity(intent.getComponent(), user,intent.getSourceBounds(), null);}}return true;} catch (SecurityException e) {Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();Log.e(TAG, "Launcher does not have the permission to launch " + intent +". Make sure to create a MAIN intent-filter for the corresponding activity " +"or use the exported attribute for this activity. "+ "tag="+ tag + " intent=" + intent, e);}return false;}

该段代码在 \packages\apps\Launcher2\src\com\android\launcher2\Launcher.java 界面中定义 , 该界面是 Launcher 应用的主界面 ;

三、 Android 应用进程分析

1 . 应用启动前置操作 :调用 startActivity(Intent intent) 方法 , 通过进程间通信 , 启动另外的 Android 应用 , 首先会去查找该 Activity 对应的包名 , 为该应用分配内存空间 , 并加载新应用对应的 main 函数 , 通过 Zygote 进程 , 孵化出新进程 , 在新进程中有方法区 , 堆区 , 栈区 , 等内存分区 ;

2 . 创建新进程过程 :Launcher 应用与 Zygote 进程进行通信后 , 通知 Zygote 进程 fork 一个新的进程 , 该新进程中通过 System Server 执行 ActivityThread , 执行 ActivityThread 中的主函数 ;

该 ActivityThread 中的主函数 main 中 , 有一个 Looper 不停的在不停的轮询读取 MessageQueue 中的消息 , 用于接收指令执行应用相关操作 ;

3 . 创建进程依据 :根据包名查找创建进程 ;

① 根据包名查找创建进程 :这个 ActivityThread 是指定包名的应用的函数入口 , 不是一个随意的入口 , 需要根据该包名查找对应的进程是否已经存在 ;

② 进程不存在 :如果这个进程不存在 , 需要重新 fork 进程 , 执行后续一系列操作 , 那么这次启动称为冷启动 ;

③ 进程存在 :如果之前该包名对应的应用存在 , 不需要重新创建进程 , 进程可以直接复用 , 那么这次启动称为热启动 ;

4 . 从进程角度分析冷启动与热启动 :

① 冷启动 :运行程序后 , 应用启动 , 会为该应用启动一个新进程 ; 这次启动是冷启动 ;

② 退出应用 进程保留 :点击回退键 , 应用退出 , 此时该进程进入后台 , 不会马上被杀死 ;

③ 热启动 :再次启动该应用时 , 就会重新启用之前的进程 , 这次启动就是热启动 ;

这也是安卓手机为什么越用越卡的原因 , 进程进入后台 , 没有及时杀死 ; 苹果手机进程进入后台 , 会放入一个与运行时不相关的内存中 ;

【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用启用普通安卓应用 | 应用进程分析 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。