美文网首页Android开发
Launcher3 快捷图标点击事件绑定到启动acitivity

Launcher3 快捷图标点击事件绑定到启动acitivity

作者: ArcherZang | 来源:发表于2020-04-05 16:05 被阅读0次
    1. void onClick(View v, String sourceContainer)->
      // ItemClickHandler.java
      // 10.0不再是ItemClickHandler.INSTANCE,只是换了一个写法返回依旧是一个OnClickListener

    2. onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);

    3. startAppShortcutOrInfoActivity(v, shortcut, launcher, sourceContainer);
      launcher.startActivitySafely(v, intent, item);
      要注意intent来自ItemInfo,如果支持FLAG_SUPPORTS_WEB_UI,会置空package

      private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
             @Nullable String sourceContainer) {
         if (TestProtocol.sDebugTracing) {
             android.util.Log.d(TestProtocol.NO_START_TAG,
                     "startAppShortcutOrInfoActivity");
         }
         Intent intent;
         if (item instanceof PromiseAppInfo) {
             PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
             intent = promiseAppInfo.getMarketIntent(launcher);
         } else {
             intent = item.getIntent();
         }
         if (intent == null) {
             throw new IllegalArgumentException("Input must have a valid intent");
         }
         if (item instanceof WorkspaceItemInfo) {
             WorkspaceItemInfo si = (WorkspaceItemInfo) item;
             if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
                     && Intent.ACTION_VIEW.equals(intent.getAction())) {
                 // make a copy of the intent that has the package set to null
                 // we do this because the platform sometimes disables instant
                 // apps temporarily (triggered by the user) and fallbacks to the
                 // web ui. This only works though if the package isn't set
                 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);
      }
      
    4. startActivitySafely(View v, Intent intent, ItemInfo item,@Nullable String sourceContainer)返回值boolean
      // Launcher.java
      中间有一个遇到意外等待重启的流程,这里我们走正常流程
      super.startActivitySafely(v, intent, item, sourceContainer)

    5. startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
      @Nullable String sourceContainer)返回值boolean
      //BaseDraggingActivity.java
      这里获取Bundle optsBundle = (v != null) ? getActivityLaunchOptionsAsBundle(v) : null;
      view不为空的情况下intent.setSourceBounds(getViewBounds(v))
      因为我们是Shortcuts所以走下面的方法

    6. startShortcutIntentSafely(intent, optsBundle, item, sourceContainer)
      不是深度链接调用startActivity(intent, optsBundle);

    7. startActivity(Intent intent, @Nullable Bundle options)
      //Activity.java
      因为options != null所以调用下面方法

    8. startActivityForResult(intent, -1, options);
      //Activity.java
      因为mParent==null所以调用下面方法

      Instrumentation.ActivityResult ar =
          mInstrumentation.execStartActivity(
              this, mMainThread.getApplicationThread(), mToken, this,
              intent, requestCode, options);
      

      参数说明:requestCode=-1
      mInstrumentation和mToken来自Activity.attach()的参数传入,
      调用者是performLaunchActivity()将ActivityThread的mInstrumentation和参数ActivityClientRecor的.token传给activity
      ActivityThread在main()方法创建自己时调用了自己的attach(false, startSeq)
      因为false所以没有走new Instrumentation();
      所以只有ActivityThread的handleBindApplication(AppBindData data)
      因为不是ClassLoader.loadClass(类名)就是new Instrumentation()所以mInstrumentation肯定不为空
      //TODO后面再分享如果自己修改默认是Instrumentation
      mToken = ActivityClientRecord.token

    9. execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,
      Intent intent, int requestCode, Bundle options) 返回值ActivityResult
      //Instrumentation.java
      参数说明:who是当前activity,contextThread是从当前activity的ActivityThread获取
      最终调用了

      IApplicationThread whoThread = (IApplicationThread) contextThread;
      Uri referrer = target != null ? target.onProvideReferrer() : null;
      //因为onProvideReferrer()返回空所以不要给Intent添加Intent.EXTRA_REFERRER
      int result = ActivityTaskManager.getService()
                      .startActivity(whoThread, who.getBasePackageName(), intent,
                              intent.resolveTypeIfNeeded(who.getContentResolver()),
                              token, target != null ? target.mEmbeddedID : null,
                              requestCode, 0, null, options)
      
    10. static getService()
      //ActivityTaskManager.java
      IActivityTaskManagerSingleton.get()
      是一个Singleton类静态实现,最终调用其中的oncreate方法
      返回的是IActivityTaskManager的binder从ServiceManager的缓存中,找不到就去ServiceManagerNative最终去native层

      • SytemServer的main方法 new SystemServer.run()
      • run()->startBootstrapServices()->
      • 最终调用了ActivityTaskManagerService atm = mSystemServiceManager.startService(
        ActivityTaskManagerService.Lifecycle.class).getService()
      • 通过反射构造了ActivityTaskManagerService.Lifecycle的实例,然后调用它的startService()方法
      • startService()中执行了两个方法,重点是publishBinderService:
        publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
        mService.start();
      • publishBinderService这个是其父类SystemService的方法
      • publishBinderService有多个重载方法,部分缺少参数默认值如下:allowIsolated=false, dumpPriority=SystemService。DUMP_FLAG_PRIORITY_DEFAULT
      • 最终调用了ServiceManager.addService(name, service, allowIsolated, dumpPriority)完成注册
      private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
           new Singleton<IActivityTaskManager>() {
               @Override
               protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
            }
      };
      
      //ServiceManager.java
      public static IBinder getService(String name) {
          try {
             IBinder service = sCache.get(name);
             if (service != null) {
                 return service;
              } else {
                   return Binder.allowBlocking(rawGetService(name));
             }
           } catch (RemoteException e) {
               Log.e(TAG, "error in getService", e);
           }
          return null;
      }
      
    11. startActivity()->startActivityAsUser()
      //ActivityTaskManagerService.java
      Linux uid/100000 4.1以上版本从100000开始,root是从0开始,每个用户加100000

        public final int startActivity(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions,
                    UserHandle.getCallingUserId());
        }
    
        public int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                    true /*validateIncomingUser*/);
        }
    
        int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
                boolean validateIncomingUser) {
            enforceNotIsolatedCaller("startActivityAsUser");
    
            userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
            // TODO: Switch to user app stacks here.
            return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setMayWait(userId)
                    .execute();
    
        }
    
    1. execute()
      // ActivityStarter.java
      因为setMayWait(userId),所以mRequest.mayWait = true;
      所以调用startActivityMayWait()内部调用了startActivity()

      startActivityMayWait(mRequest.caller, mRequest.callingUid,
                          mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                          mRequest.intent, mRequest.resolvedType,
                          mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                          mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                          mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                          mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                          mRequest.inTask, mRequest.reason,
                          mRequest.allowPendingRemoteAnimationRegistryLookup,
                          mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart)
      
    2. startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
      voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
      callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
      ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
      allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
      allowBackgroundActivityStart)

    3. startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
      mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
      mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
      mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
      mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
      mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
      mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
      mRequest.outActivity, mRequest.inTask, mRequest.reason,
      mRequest.allowPendingRemoteAnimationRegistryLookup);
      //ActivityStarter.java

    4. mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
      aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
      callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
      options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
      inTask, allowPendingRemoteAnimationRegistryLookup);
      //ActivityStarter.java
      // 方法内部创建了ActivityRecord

    5. startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
      true /* doResume */, checkedOptions, inTask, outActivity)
      //ActivityStarter.java

    6. result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
      startFlags, doResume, options, inTask, outActivity);

    7. mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,
      mStartActivity, mOptions)
      // mSupervisor是在AMS中创建最终传入ActivityStarter
      // ActivityStackSupervisor.java
      // mTargetStack 通过新建TaskRecord创建
      // TO do有空细化

    8. targetStack.resumeTopActivityInnerLocked(target,
      targetOptions)
      // ActivityStack.java

    9. mStackSupervisor.startSpecificActivityLocked(target,
      targetOptions)
      // ActivityStackSupervisor.java

    10. Service.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
      "activity", r.intent.getComponent(), false, false, true)
      // ActivityManagerService.java
      // 经过一阵startProcessLocked重载方法传递

    11. startProcess(hostingType, entryPoint, app,
      uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
      invokeWith, startTime)

    12. Process.start(entryPoint,
      app.processName, uid, uid, gids, runtimeFlags, mountExternal,
      app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
      app.info.dataDir, invokeWith,
      new String[] {PROC_START_SEQ_IDENT + app.startSeq})

    13. zygoteProcess.start(processClass, niceName, uid, gid, gids,
      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
      abi, instructionSet, appDataDir, invokeWith, zygoteArgs)

    14. startViaZygote(processClass, niceName, uid, gid, gids,
      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
      abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote /,
      zygoteArgs)

    15. startViaZygote(processClass, niceName, uid, gid, gids,
      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
      abi, instructionSet, appDataDir, invokeWith, false /
      startChildZygote /,
      zygoteArgs)

    16. zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
      openZygoteSocketIfNeeded(abi)方法使用socket与ZygoteProcess进程通信,
      zygoteSendArgsAndGetResult方法主要写入参数
      其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法

    17. **[ZygoteInit.java] main()****

      说明:Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher

    18. [ZygoteConnection.java] processOneCommand()

      说明:通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理

    19. [ZygoteConnection.java] handleChildProc()
      说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()

    20. [ZygoteConnection.java] zygoteInit()进行一些环境的初始化、启动Binder进程等操作:

    21. 把之前传来的"android.app.ActivityThread" 传递给findStaticMain():

      通过反射,拿到ActivityThread的main()方法:
      把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:

    22. main(String[] args)

      //ActivityThread.java

    ActivityThread thread = new ActivityThread();
    //ActivityThread实例化时其属性mAppThread也实例化
    //final ApplicationThread mAppThread = new ApplicationThread();
    thread.attach(false, startSeq);
    
    1. attach(boolean system, long startSeq)
      //ActivityThread.java

      • ActivityManager.getService()
        //ActivityManager.java

        1. ServiceManager.getService(Context.ACTIVITY_SERVICE)

          BinderInternal.getContextObject()最终调用native层方法获取的是ActivityManagerService的binder

          简单叙述AMS注册过程

          SystemServer的static void main(String[] args)

          ---->run()

          ----> mSystemServiceManager = new SystemServiceManager(mSystemContext);

          ---->startBootstrapServices()
          -------->1. mActivityManagerService = mSystemServiceManager.startService(
          ActivityManagerService.Lifecycle.class).getService();
          -------->SystemServiceManager的startService(Class<T> serviceClass)
          -------->最终反射实例调用,因为ActivityManagerService.Lifecycle extends SystemService service.onStart()
          -------->ActivityManagerService.Lifecycle.onStart()
          -------->因为构造Lifecycle时内部mService = new ActivityManagerService(context, sAtm);
          在构造方法内部创建了mStackSupervisor = createStackSupervisor();
          protected ActivityStackSupervisor
          -------->ActivityManagerService.Lifecycle.getService()返回内部mService
          -------->2.mActivityManagerService.setSystemProcess();在startBootstrapServices()里面调用
          ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
          DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO)

        2. mgr.attachApplication(mAppThread, startSeq)
          // ActivityManagerService.java

    2. attachApplicationLocked(thread, callingPid, callingUid, startSeq)
      // ActivityManagerService.java
      //----->thread.bindApplication()
      这里的thread是最上面提到的ApplicationThread是ActivityThread的内部类,是binder

    3. sendMessage(H.BIND_APPLICATION, data);
      //ActivityThread.java

    4. 最终走到H类的handleBindApplication(data)

      • InstrumentationInfo ii = new ApplicationPackageManager(null, getPackageManager())
        .getInstrumentationInfo(data.instrumentationName, 0)
        IF----data.instrumentationName == null, ii = null

      • IF---- ii!=null ----

        ​ final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
        ​ appContext.getClassLoader(), false, true, false);
        ​ final ContextImpl instrContext = ContextImpl.createAppContext(this, pi)

        ELSE ----
        mInstrumentation = new Instrumentation();

        END IF;

      • instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
        appContext.getClassLoader(), false, true, false);

      • final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

      • Application app = data.info.makeApplication(data.restrictedBackupMode, null)

        IF--------如果LoadedApk的mApplication中不为空就返回mApplication,
        ELSE ---如果为空就

        先得到String appClass = mApplicationInfo.className;
        再获取java.lang.ClassLoader cl = getClassLoader();
        再创建ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this)
        最终通过app = mActivityThread.mInstrumentation.newApplication(
        cl, appClass, appContext)创建,
        END IF-----

      • mInstrumentation.callApplicationOnCreate(app);

        app.onCreate()

      • 最后我们返回ActivityManagerService.attachApplicationLocked()继续往下

    5. mStackSupervisor.attachApplicationLocked(app)
      // //ActivityStackSupervisor.java
      // 来自ActivityManagerService.attachApplicationLocked(thread, callingPid, callingUid, startSeq)

    6. ---->realStartActivityLocked(activity, app, top == activity /* andResume /, true / checkConfig */)
      //ActivityStackSupervisor.java

    7. mService.getLifecycleManager().scheduleTransaction(clientTransaction)
      // ActivityManagerService.java --- mService
      // ClientLifecycleManager.java --- mService.getLifecycleManager()
      // final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
      // 在ActivityStackSupervisor.realStartActivityLocked()方法内部构造
      // ClientLifecycleManager.scheduleTransaction(ClientTransaction transaction)

    8. mLifecycleManager.scheduleTransaction(ClientTransaction transaction)
      // ClientLifecycleManager.java

    9. transaction.schedule()
      // ClientTransaction.java

    10. mClient.scheduleTransaction(this)

      //ApplicationThread.java

    11. ActivityThread.this.scheduleTransaction(transaction);

    12. ClientTransactionHandler.scheduleTransaction(transaction)
      // ActivityThread extends ClientTransactionHandler

    13. sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

      // ClientTransactionHandler.java

    14. handleMessage(Message msg)
      // ActivityThread.H.

    15. mTransactionExecutor.execute(transaction);
      //final ClientTransaction transaction = (ClientTransaction) msg.obj;
      // TransactionExecutor.java 是ActivityThread的属性,定义时就初始化了
      // private TransactionExecutor mTransactionExecutor = new TransactionExecutor(this)

    16. executeCallbacks(transaction);
      // TransactionExecutor.java

      1. final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    17. item.execute(mTransactionHandler, token, mPendingActions);

      //LaunchActivityItem.java

      //在ActivityStackSupervisor的realStartActivityLocked()方法构造transaction
      

      ​ //构造clientTransaction后将LaunchActivityItem添加入Callbacks

      ​ //最后后作为sendMessage参数传递过来

      ​ //在handleMessage方法中做了转换

       final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
               r.appToken);
       clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
               System.identityHashCode(r), r.info,
               // TODO: Have this take the merged configuration instead of separate global
               // and override configs.
               mergedConfiguration.getGlobalConfiguration(),
               mergedConfiguration.getOverrideConfiguration(), r.compat,
               r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
               r.persistentState, results, newIntents, mService.isNextTransitionForward(),
               profilerInfo));
      
    18. client.handleLaunchActivity(r, pendingActions, null /* customIntent */);

    19. //ActivityStackSupervisor.realStartActivityLocked()内

    20. client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
      因为ActivityThread extends ClientTransactionHandler且ActivityThread 覆写了此方法

    21. final Activity a = performLaunchActivity(r, customIntent)
      // ActivityThread.Java

      • ComponentName component = r.intent.getComponent()

      • 新建ContextImpl appContext = createBaseContextForActivity(r)

      • 通过 mInstrumentation.newActivity(cl, component.getClassName(), r.intent)创建 Activity

        /frameworks/base/java/android/app/Instrumentation.java

        getFactory(pkg).instantiateActivity(cl, className, intent)

        1. getFactory(pkg)

        ​ LoadedApk apk = mThread.peekPackageInfo(pkg, true); apk.getAppFactory()

        ​ LoadedApk构造时创建了AppComponentFactory

        1. AppComponentFactory.instantiateActivity(cl, className, intent)

        ​ 最终通过classloader加载类,然后newInstance()

      • Application app = r.packageInfo.makeApplication(false, mInstrumentation)

        IF--------如果LoadedApk的mApplication中不为空就返回mApplication,
        ELSE ---如果为空就

        先得到String appClass = mApplicationInfo.className;
        再获取java.lang.ClassLoader cl = getClassLoader();
        再创建ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this)
        最终通过app = mActivityThread.mInstrumentation.newApplication(
        cl, appClass, appContext)创建,
        END IF-----

      • 调用Acitivity的attach方法
        activity.attach(appContext, this, getInstrumentation(), r.token,
        r.ident, app, r.intent, r.activityInfo, title, r.parent,
        r.embeddedID, r.lastNonConfigurationInstances, config,
        r.referrer, r.voiceInteractor, window, r.configCallback);
        Activity extends ContextThemeWrapper
        ContextThemeWrapper extends ContextWrapper
        ContextWrapper extends Context
        Activity的attach()方法通过attachBaseContext一层一层往上调用传递

      • mInstrumentation.callActivityOnCreate(activity....)传入activity最终调用acitivity的onCreate方法

        r.isPersistable()是否持久模式重启
        IF--true---ImInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        ELSE------mInstrumentation.callActivityOnCreate(activity, r.state);

        正常我们走else

        END IF----activity.performCreate(icicle, persistentState)

        最终都会activity.performCreate(Bundle icicle, PersistableBundle persistentState),只是最后一个参数有可能空
        activity.onCreate(icicle)
        我们在activity中setContentView(R.layout.activity_main);加载我们的布局

    相关文章

      网友评论

        本文标题:Launcher3 快捷图标点击事件绑定到启动acitivity

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