美文网首页Android
App启动流程

App启动流程

作者: 猿规 | 来源:发表于2021-08-30 15:55 被阅读0次

    源码标准:API : 29「Android 10.0」
    补充知识点:
    上一篇讲了Android开机流程,就是Zygote开始fork出SystemServer进程。
    在SystemServer中会创建一个socket接口来监听请求以及初始化AMS。
    根据请求,Zygote会基于自身,预先加载的虚拟机来创建一个新的虚拟机,创建一个新的进程,来管理新的App进程。

    为什么点击手机屏幕上的图标就能打开app?

    屏幕本质上就是一个程序app,当我们安装好app后就会出现一个图标。

    /packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

    /**
     * Default launcher application.
     * 也就是桌面
     */
    public class Launcher extends BaseDraggingActivity implements LauncherExterns,
            LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate,
            InvariantDeviceProfile.OnIDPChangeListener {
        public static final String TAG = "Launcher";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);
              setContentView(mLauncherView);
        }
    
    }
    

    Launcher「桌面」 进程通过 Binder ICP 机制,通知ActivityManagerService「AMS」来创建新的进程。
    也就是ActivityThread「UI线程」(Activity运行在ActivityThread实例中)。

    ActivityThread通过 Binder ICP 机制将Binder对象传递给AMS,彼此进行通信。

    当点击app图标。

       /**
         * Creates a view representing a shortcut inflated from the specified resource.
         *
         * @param parent The group the shortcut belongs to.
         * @param info The data structure describing the shortcut.
         * @return A View inflated from layoutResId.
         */
        public View createShortcut(ViewGroup parent, WorkspaceItemInfo info) {
            BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.app_icon, parent, false);
            favorite.applyFromWorkspaceItem(info);
            favorite.setOnClickListener(ItemClickHandler.INSTANCE);
            favorite.setOnFocusChangeListener(mFocusHandler);
            return favorite;
        }
    

    这里定位到具体的点击holder类。

    /packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java

    /**
     * Class for handling clicks on workspace and all-apps items
     */
    public class ItemClickHandler {
    
    private static void onClick(View v, String sourceContainer) {
         
            Launcher launcher = Launcher.getLauncher(v.getContext());
            Object tag = v.getTag();
            if (tag instanceof WorkspaceItemInfo) {
                onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
            } else if (tag instanceof FolderInfo) {
                if (v instanceof FolderIcon) {
                    onClickFolderIcon(v);
                }
            } else if (tag instanceof AppInfo) {
                //app类型点击
                startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher,
                        sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer);
            } else if (tag instanceof LauncherAppWidgetInfo) {
                if (v instanceof PendingAppWidgetHostView) {
                    onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
                }
            }
        }
    
       /**
         * Event handler for an app shortcut click.
         * @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}.
         */
        public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher,
                @Nullable String sourceContainer) {
            // Check for abandoned promise
            if ((v instanceof BubbleTextView) && shortcut.hasPromiseIconUi()) {
                String packageName = shortcut.intent.getComponent() != null ?
                        shortcut.intent.getComponent().getPackageName() : shortcut.intent.getPackage();
                if (!TextUtils.isEmpty(packageName)) {
                    onClickPendingAppItem(v, launcher, packageName,
                            shortcut.hasStatusFlag(WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE));
                    return;
                }
            }
            // Start activities
            startAppShortcutOrInfoActivity(v, shortcut, launcher, sourceContainer);
        }
    
        private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
                @Nullable String sourceContainer) {
            Intent intent;
            if (item instanceof PromiseAppInfo) {
                PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
                intent = promiseAppInfo.getMarketIntent(launcher);
            } else {
                intent = item.getIntent();
            }
            if (item instanceof WorkspaceItemInfo) {
                WorkspaceItemInfo si = (WorkspaceItemInfo) item;
                if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
                        && Intent.ACTION_VIEW.equals(intent.getAction())) {
                    intent = new Intent(intent);
                    intent.setPackage(null);
                }
            }
            if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation()) {
                // Preload the icon to reduce latency b/w swapping the floating view with the original.
                FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
            }
            launcher.startActivitySafely(v, intent, item, sourceContainer);
        }
    }
    

    真是从里寻他千百度,我快进入死循环里出不来了,多少有点费劲。
    最后通过startActivitySafely方法,在新的Task中启动MainActivity。

    相关文章

      网友评论

        本文标题:App启动流程

        本文链接:https://www.haomeiwen.com/subject/wbmevltx.html