Android App應用啟動流程(一)
本篇原始碼分析基於Android8.0 API 26
關於Android原始碼檢視:
你可以去看這裡: 線上檢視,也可以在Android Studio裡面關聯原始碼,也可以完全下載自己去編譯
Launcher中的App列表使用的RecyclerView
//public class AllAppsRecyclerView extends BaseRecyclerView//public abstract class BaseRecyclerView extends RecyclerView//AllAppsRecyclerView最終繼承自RecyclerView
這個Activity叫做Launcher.java,既然是RecyclerView,我們很自然的想到了item點選事件,item點選事件其實是對item設定的View.OnClickListener事件,恰巧Launcher實現了這個事件
/** * Default launcher application. */public class Launcher extends BaseActivity implements LauncherExterns, View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, View.OnTouchListener, LauncherProviderChangeListener, AccessibilityManager.AccessibilityStateChangeListener, WallpaperColorInfo.OnThemeChangeListener {
那麼是不是這裡就是用來處理RecyclerView應用圖示的點選事件呢?答案是yes
給AllAppsRecyclerView設定adapter被封裝到了AllAppsContainerView裡面,然後AllAppsContainerView裡面
mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this);
AllAppsGridAdapter
/** * The grid view adapter of all the apps. */ public class AllAppsGridAdapter extends RecyclerView.Adapter{ ... //AllAppsGridAdapter建構函式傳入iconClickListener public AllAppsGridAdapter(Launcher launcher, AlphabeticalAppsList apps, View.OnClickListener iconClickListener, View.OnLongClickListener iconLongClickListener) { Resources res = launcher.getResources(); mLauncher = launcher; mApps = apps; mEmptySearchMessage = res.getString(R.string.all_apps_loading_message); mGridSizer = new GridSpanSizer(); mGridLayoutMgr = new AppsGridLayoutManager(launcher); mGridLayoutMgr.setSpanSizeLookup(mGridSizer); mLayoutInflater = LayoutInflater.from(launcher); mIconClickListener = iconClickListener; mIconLongClickListener = iconLongClickListener; if (FeatureFlags.LAUNCHER3_PHYSICS) { mSpringAnimationHandler = new SpringAnimationHandler( SpringAnimationHandler.Y_DIRECTION, new AllAppsSpringAnimationFactory()); } } ... @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_ICON: case VIEW_TYPE_PREDICTION_ICON: //icon點選事件 BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( R.layout.all_apps_icon, parent, false); icon.setOnClickListener(mIconClickListener); icon.setOnLongClickListener(mIconLongClickListener); icon.setLongPressTimeout(ViewConfiguration.getLongPressTimeout()); icon.setOnFocusChangeListener(mIconFocusListener); // Ensure the all apps icon height matches the workspace icons in portrait mode. icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx; return new ViewHolder(icon); ... } } ...}
可見這個點選事件被設定上了,現在我們回去看看Launcher.java這個Activity裡面的onClick事件
/** * Launches the intent referred by the clicked shortcut. * * @param v The view representing the clicked shortcut. */public void onClick(View v) { ... Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { onClickAppShortcut(v); } else if (tag instanceof FolderInfo) { if (v instanceof FolderIcon) { onClickFolderIcon(v); } } else if ((v instanceof PageIndicator) || (v == mAllAppsButton && mAllAppsButton != null)) { onClickAllAppsButton(v); } else if (tag instanceof AppInfo) { //執行這裡 startAppShortcutOrInfoActivity(v); } else if (tag instanceof LauncherAppWidgetInfo) { if (v instanceof PendingAppWidgetHostView) { onClickPendingWidget((PendingAppWidgetHostView) v); } } }//拿到應用資訊,執行startActivitySafely(v, intent, item)private void startAppShortcutOrInfoActivity(View v) { ItemInfo item = (ItemInfo) v.getTag(); Intent intent; if (item instanceof PromiseAppInfo) { PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item; intent = promiseAppInfo.getMarketIntent(); } else { intent = item.getIntent(); } if (intent == null) { throw new IllegalArgumentException("Input must have a valid intent"); } boolean success = startActivitySafely(v, intent, item); getUserEventDispatcher().logAppLaunch(v, intent); // TODO for discovered apps b/35802115 if (success && v instanceof BubbleTextView) { mWaitingForResume = (BubbleTextView) v; mWaitingForResume.setStayPressed(true); } }public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ... // 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); Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions(v) : null; UserHandle user = item == null ? null : item.user; // Prepare intent intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (v != null) { intent.setSourceBounds(getViewBounds(v)); } try { if (Utilities.ATLEAST_MARSHMALLOW && (item instanceof ShortcutInfo) && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) && !((ShortcutInfo) item).isPromise()) { // Shortcuts need some special checks due to legacy reasons. startShortcutIntentSafely(intent, optsBundle, item); } else if (user == null || user.equals(Process.myUserHandle())) { // Could be launching some bookkeeping activity startActivity(intent, optsBundle); } else { LauncherAppsCompat.getInstance(this).startActivityForProfile( intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } return true; } catch (ActivityNotFoundException|SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e); } return false; }
可以看到最後執行的是startActivity方法,startActivity是Activity的方法,關於app圖示點選事件先講到這。
原文出處
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/855/viewspace-2801645/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android 應用啟動流程Android
- Android應用啟動流程分析Android
- Android APP 冷啟動流程AndroidAPP
- flutter 應用啟動流程Flutter
- App啟動流程APP
- 原始碼閱讀之Activity啟動與App啟動流程 – Android 9.0原始碼APPAndroid
- 原始碼閱讀之Activity啟動與App啟動流程 - Android 9.0原始碼APPAndroid
- framework——應用程式啟動流程Framework
- FlutterEngin啟動流程&androidFlutterAndroid
- App 竟然是這樣跑起來的 —— Android App/Activity 啟動流程分析APPAndroid
- android app 啟動第一個頁面AndroidAPP
- Android 系統啟動流程Android
- Android 9.0 init 啟動流程Android
- Spring Boot 應用程式啟動流程分析Spring Boot
- 梳理一下Android 系統啟動流程Android
- Android App啟動過程AndroidAPP
- Android原始碼(二)應用程式啟動Android原始碼
- Android系統啟動流程(四)Launcher啟動過程與系統啟動流程Android
- app啟動流程,activity啟動流程時序圖,binder相關資料APP時序圖
- 一張圖輕鬆掌握 Flink on YARN 應用啟動全流程(上)Yarn
- Android 應用啟動那些事兒,Application? Context?AndroidAPPContext
- Android Activity啟動流程原始碼分析Android原始碼
- Flutter Android 端啟動流程淺析FlutterAndroid
- Android原始碼分析:Activity啟動流程Android原始碼
- 深入理解Android 之 Activity啟動流程(Android 10)Android
- (連載)Android 8.0 : 系統啟動流程之init程式(一)Android
- Android應用優化之冷啟動優化Android優化
- Activity 的 "啟動流程"(基於 Android 9.0)Android
- [譯] 在 Android Instant App(安卓即時應用程式)中啟用 ProGuard (混淆)AndroidAPP安卓
- Android 裝逼技術之暗碼啟動應用Android
- Android效能最佳化之加快應用啟動速度Android
- Android LocationManagerService啟動(一)Android
- Android系統啟動流程(二)解析Zygote程式AndroidGo
- Android系統原始碼分析--Service啟動流程Android原始碼
- Android系統原始碼分析–Service啟動流程Android原始碼
- Android應用關閉,重啟Android
- iOS-APP的啟動流程和生命週期iOSAPP
- Android小知識-深入淺出Android系統啟動流程(上)Android