Activity的启动过程(Android 9 API 28)

举报
yd_221104950 发表于 2020/12/02 23:48:43 2020/12/02
【摘要】 Android应用目前基本都用Java语言来编写。操作系统在执行代码时,总要知道从哪里开始执行。因此编程语言都约定main()函数作为应用程序的入口。自然Java也不例外。Android应用的入口 main()函数在ActivityThread这个类中。 平时我们写Android应用时,更关注Activity的生命周期,那么这一系列的生命周期方法是什么时候执行的都是在...

Android应用目前基本都用Java语言来编写。操作系统在执行代码时,总要知道从哪里开始执行。因此编程语言都约定main()函数作为应用程序的入口。自然Java也不例外。Android应用的入口 main()函数在ActivityThread这个类中

平时我们写Android应用时,更关注Activity的生命周期,那么这一系列的生命周期方法是什么时候执行的都是在ActivityThread类里规定好的。onCreate、onResume是不是有点像钩子方法。

1.ActivityThread类的main()函数

 public static void main(String[] args) { // ... // 初始化当前线程为循环器,将它标记为应用程序的主循环器。应用程序的主循环器是由Android 环境创建的, 所以我们不应该自己调用此函数 Looper.prepareMainLooper(); // 创建ActivityThread对象,并调用attach方法 ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // ... // 在此线程中运行消息队列。需要调用quit()方法来结束循环。 Looper.loop(); // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2.ActivityThread类的attach()方法

private void attach(boolean system, long startSeq) { // 记录ActivityThread sCurrentActivityThread = this; // 这里system传进来的是false,表示非系统的 if (!system) { // ... // 获得ActivityManagerService对像。它是一个单例对象,即在全局只有一个。 final IActivityManager mgr = ActivityManager.getService(); try { // 传入的mAppThread参数为ActivityThread的内部类ApplicationThread对象 // 创建Activity的队列消息就是由这个内部类发出的。 mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } // ... } // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

我们看看ActivityManagerService的attachApplication()方法。

3.ActivityManagerService的attachApplication()方法

 @Override public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); // 再继续调4个参数的attachApplicationLocked方法 attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.ActivityManagerService的attachApplicationLocked()方法

// thread是一个ApplicationThread对象 
private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { // 这个app会缓存ApplicationThread对象 ProcessRecord app; // ... // 缓存ApplicationThread app.makeActive(thread, mProcessStats); // ... boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); // ... try { // ...  // 这里的thread就是ApplicationThread对象 // 通过ApplicationThread对象中的bindApplication()方法来了解它 if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } // ... } catch (Exception e) { // ... } // 启动第一个Activity if (normalMode) { try { // Application初始化之后,初始化&启动第一个Activity // mStackSupervisor是ActivityStackSupervisor对象 // 这个方法将会执行ApplicationThread中的scheduleLaunchActivity()方法 // 通过ActivityStackSupervisor对象中的attachApplicationLocked()方法来了解它 if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { // ... } } // ...  return true; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

4.1.ApplicationThread对象中的bindApplication()方法

在Android项目中一般都会指定一个Application类,该类也拥有诸如 onCreate()等生命周期的方法。而且Application类的 onCreate()方法会比第一个Activity的 onCreate()先被执行。为什么这样呢?上面的代码中 thread.bindApplication()方法可以告诉我们答案。thread是ApplicationThread对象(ApplicationThread是ActivityThread的内部类),它的 bindApplication()如下:

 public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial, boolean autofillCompatibilityEnabled) { // ... // 这里发送一个队列消息用于绑定Application // 这里的队列消息是由Handler的子类 H 类发送,H类也是ActivityThread的内部类  sendMessage(H.BIND_APPLICATION, data); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

根据上面发送的队列消息,我最终追踪到它会执行ActivityThread类的handleBindApplication()方法:

private void handleBindApplication(AppBindData data) { // ... // Instrumentation信息会影响类加载器,因此请在设置应用上下文之前加载它 final InstrumentationInfo ii; // ... if (ii != null) { // ...	 } else { // 在这里创建了Instrumentation对象,这个对象在后面Activity的生命周期方法的调用方面起着至关重要的作用 mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); } // ... try { // ... try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { // ... } try { // 调用我们的Application类的onCreate()方法 mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { // ... } } finally { // ... } // ...
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

Instrumentation类的callApplicationOnCreate()方法:

public void callApplicationOnCreate(Application app) { // 调用Application的onCreate()方法 app.onCreate(); }

  
 
  • 1
  • 2
  • 3
  • 4

4.2.ActivityStackSupervisor对象中的attachApplicationLocked()方法

ActivityManagerServiceattachApplicationLocked()方法里,我们知道系统调用了ActivityStackSupervisor对象的attachApplicationLocked(app)方法,传入的app是一个ProcessRecord对象。该对象缓存了ApplicationThread对象。

 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { // ... try { // Application初始化之后,启动第一个Activity if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } } catch (RemoteException e) { // ... } // ... return didSomething; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

ActivityStackSupervisor对象中的realStartActivityLocked()方法:

 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { // ... // TAG1  创建activity启动事务 // 通知ActivityThread创建activity的实例 ;调用Activity的OnCreate; 创建对应PhoneWindow实例 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)); // Set desired final state.设置期望的最终状态 final ActivityLifecycleItem lifecycleItem; if (andResume) { // Activity启动之后生命周期变化为Resume的流程 lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { // Activity启动之后生命周期变化为Pause的流程 lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // TAG2 // 启动Activity实例的事务,并按顺序调用onCreate();onStart();onResume(); mService.getLifecycleManager().scheduleTransaction(clientTransaction); // ... return true; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

TAG1:ClientTransaction类的obtain()方法。

 /** 用提供的参数获得初始化了的实例 */ public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) { ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class); if (instance == null) { instance = new ClientTransaction(); } instance.mClient = client; instance.mActivityToken = activityToken; return instance; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

ClientTransaction类的addCallback()方法。

/** 在回调序列的末尾添加一条消息。消息包含生命周期请求/回调的消息  */ public void addCallback(ClientTransactionItem activityCallback) { if (mActivityCallbacks == null) { mActivityCallbacks = new ArrayList<>(); } mActivityCallbacks.add(activityCallback); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

消息生成是由LaunchActivityItem类的obtain()来完成

 /** 获取使用提供的参数初始化的实例 */ public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo) { LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); if (instance == null) { instance = new LaunchActivityItem(); } setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer, voiceInteractor, procState, state, persistentState, pendingResults, pendingNewIntents, isForward, profilerInfo); return instance; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

TAG2:通过ClientLifecycleManagerscheduleTransaction()启动事务;

 /** 安排一个事务,该事务可能包含多个回调和一个生命周期请求。即启动Activity实例的事务,并按顺序调用onCreate();onStart();onResume(); */ void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { // If client is not an instance of Binder - it's a remote call and at this point it is // safe to recycle the object. All objects used for local calls will be recycled after // the transaction is executed on client in ActivityThread. transaction.recycle(); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

ClientTransactionschedule()函数

/** 初始化后安排事务。它将发送到客户端及其所有各个部件将按以下顺序应用 */ /** * 在事务对象初始化后,就安排事件的执行。它将被送到客户端,各个部分都将按以下顺序来应用: * 1. 客户端调用preExecute(ClientTransactionHandler),它将在实际调度回调和生命周期状态请求的事务之前触发所有需要做的工作。 * 2. 事务消息已计划。 * 3. 客户端调用TransactionExecutor的execute(ClientTransaction)方法,它会执行所有回调和必要的生命周期转换。 */
public void schedule() throws RemoteException { // mClient就是与ActivityThread通讯的代理对象(IApplicationThread),所以这里其实是调用ActivityThread类中ApplicationThread内部类的scheduleTransaction(); mClient.scheduleTransaction(this); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

ApplicationThreadscheduleTransaction()函数

 @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); }

  
 
  • 1
  • 2
  • 3
  • 4

最后调用了ActivityThreadscheduleTransaction()scheduleTransaction()的实现是ActivityThread的父类ClientTransactionHandler

 /** Prepare and schedule transaction for execution. */ void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); // 调用ActivityThread的sendMessage(),将ClientTransaction参数通过Handler机制切换至主线程进行处理 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

ActivityThreadH类:

 class H extends Handler { //... public void handleMessage(Message msg) { switch (msg.what) { case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; // 通过TransactionExecutor真正处理ClientTransaction中封装的Activity相关信息 mTransactionExecutor.execute(transaction); if (isSystem()) { // Client transactions inside system process are recycled on the client side // instead of ClientLifecycleManager to avoid being cleared before this // message is handled. transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break; } } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

TransactionExecutorexecute()方法处理ClientTransaction:

 public void execute(ClientTransaction transaction) { // ... // 最终执行onCreate executeCallbacks(transaction); // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

TransactionExecutorexecuteCallbacks()启动Activity:

public void executeCallbacks(ClientTransaction transaction) { // ... for (int i = 0; i < size; ++i) { // 获取ClientTransaction中的ClientTransactionItem对象,其实这里的对象就上面介绍中的LaunchActivityItem final ClientTransactionItem item = callbacks.get(i); // ... // 因此,这里调用LaunchActivityItem类的execute() item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); f (r == null) { // Launch activity request will create an activity record. r = mTransactionHandler.getActivityClient(token); } // ... if (postExecutionState != UNDEFINED && r != null) { // Skip the very last transition and perform it by explicit state request instead. final boolean shouldExcludeLastTransition = i == lastCallbackRequestingState && finalState == postExecutionState; // TAG_OTHER cycleToPath(r, postExecutionState, shouldExcludeLastTransition); } } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

LaunchActivityItem类的execute():

 @Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { // ... // 经过多次不同层次相互调用,最终真正调用ActivityThread的handleLaunchActivity(),启动应用的第一个Activity; client.handleLaunchActivity(r, pendingActions, null /* customIntent */); // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ActivityThreadhandleLaunchActivity()

 @Override public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { // ... WindowManagerGlobal.initialize(); // 启动Activity final Activity a = performLaunchActivity(r, customIntent); // ... } // ... return a; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

ActivityThreadperformLaunchActivity()的方法 ,执行启动Activity:

 /**  Activity 启动的核心实现 */ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // ... if (r.isPersistable()) { // 调用Activity的onCreate方法 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { // 调用Activity的onCreate方法 mInstrumentation.callActivityOnCreate(activity, r.state); } // ... } // ... return activity; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

InstrumentationcallActivityOnCreate()方法

 /** 执行Activity的onCreate方法 */ public void callActivityOnCreate(Activity activity, Bundle icicle) {
		// ... // 执行Activity的onCreate方法 activity.performCreate(icicle); // ... } /** 执行Activity的onCreate方法 */ public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { // ... // 执行Activity的onCreate方法 activity.performCreate(icicle, persistentState); // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Activity类的performCreate()方法:

 final void performCreate(Bundle icicle) { performCreate(icicle, null); } final void performCreate(Bundle icicle, PersistableBundle persistentState) { // ... if (persistentState != null) { // 执行Activity的onCreate方法 onCreate(icicle, persistentState); } else { // 执行Activity的onCreate方法 onCreate(icicle); } // ... }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

TAG_OTHER:
TransactionExecutorcycleToPath():

 private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState) { final int start = r.getLifecycleState(); log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState); final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); performLifecycleSequence(r, path); } /** Transition the client through previously initialized state sequence. */ private void performLifecycleSequence(ActivityClientRecord r, IntArray path) { final int size = path.size(); for (int i = 0, state; i < size; i++) { state = path.get(i); log("Transitioning to state: " + state); switch (state) { case ON_CREATE: mTransactionHandler.handleLaunchActivity(r, mPendingActions, null /* customIntent */); break; case ON_START: mTransactionHandler.handleStartActivity(r, mPendingActions); break; case ON_RESUME: mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */, r.isForward, "LIFECYCLER_RESUME_ACTIVITY"); break; case ON_PAUSE: mTransactionHandler.handlePauseActivity(r.token, false /* finished */, false /* userLeaving */, 0 /* configChanges */, mPendingActions, "LIFECYCLER_PAUSE_ACTIVITY"); break; case ON_STOP: mTransactionHandler.handleStopActivity(r.token, false /* show */, 0 /* configChanges */, mPendingActions, false /* finalStateRequest */, "LIFECYCLER_STOP_ACTIVITY"); break; case ON_DESTROY: mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */, 0 /* configChanges */, false /* getNonConfigInstance */, "performLifecycleSequence. cycling to:" + path.get(size - 1)); break; case ON_RESTART: mTransactionHandler.performRestartActivity(r.token, false /* start */); break; default: throw new IllegalArgumentException("Unexpected lifecycle state: " + state); } } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

以上是app启动的过程。那么启动后,调用startActivity()方法来启动其他Activity,最终会通过ActivityThread的sendActivityResult()方法来进行启动,过程和上面类似:

 public final void sendActivityResult( IBinder token, String id, int requestCode, int resultCode, Intent data) { if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id + " req=" + requestCode + " res=" + resultCode + " data=" + data); ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); list.add(new ResultInfo(id, requestCode, resultCode, data)); final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, token); clientTransaction.addCallback(ActivityResultItem.obtain(list)); try { mAppThread.scheduleTransaction(clientTransaction); } catch (RemoteException e) { // Local scheduling } }


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/107308852

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。