日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2025/6/17 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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 应用启用普通安卓应用 | 应用进程分析 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。