Adapting Android P Activity Lifecycle Hooks for the 分身大师 Plugin Framework
This article explains how Android P refactors the Activity lifecycle handling, details the shift from LAUNCH_ACTIVITY messages to EXECUTE_TRANSACTION processing, and describes the necessary code adaptations for the 分身大师 framework to support dual‑open apps on Android P.
Android P Activity Lifecycle Changes
分身大师 is a highly invasive plugin framework that directly runs user‑cloned apps, but its many hooks make it sensitive to system updates; changes in Android P’s framework, especially Activity lifecycle restructuring, require a series of adaptations.
1.1 ActivityThread Message Changes
Before Android P, 分身大师 hooked the ActivityThread message flow, intercepting the LAUNCH_ACTIVITY message to replace placeholder Activities with real ones. The following images compare the full message lists of Android O and Android P.
Android O message list:
Android P message list:
Comparison shows that in Android P the messages from LAUNCH_ACTIVITY to DESTROY_ACTIVITY have been removed; all Activity lifecycle handling is now performed inside the EXECUTE_TRANSACTION message.
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;1.2 EXECUTE_TRANSACTION Processing
The EXECUTE_TRANSACTION message carries a ClientTransaction object, and the actual work is delegated to TransactionExecutor. Core business logic resides in ClientTransactionItem subclasses.
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}The relationship between ClientTransactionHandler and its items is illustrated below.
Each ClientTransactionItem implements an abstract interface that manages a specific Activity lifecycle stage. The launch flow is handled by the LaunchActivityItem subclass, whose execute method is similar to the old LAUNCH_ACTIVITY handling.
1.3 Activity Launch Sequence in Android P
Adapting 分身大师 for Android P
2.1 Placeholder Replacement
The launch method remains unchanged, so the strategy of swapping the real Activity with a placeholder Activity by hooking startActivity and replacing the Intent stays the same.
2.2 Placeholder Restoration
Restoring the placeholder involves replacing the placeholder Activity with the real one after the AMS message reaches the ActivityThread. In Android P, ActivityClientRecord is created inside the LaunchActivityItem.execute method rather than during the LAUNCH_ACTIVITY message.
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState,
mPersistentState, mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}On the AMS side, ClientTransaction is built in ActivityStackSupervisor.realStartActivityLocked and sent to the client via ClientLifeCycleManager:
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
clientTransaction.addCallback(
LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r),
r.info,
configs.mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(),
r.compat,
r.launchedFromPackage,
task.voiceInteractor,
app.repProcState,
r.icicle,
r.persistentState,
results,
newIntents,
mService.isNextTransitionForward(),
profilerInfo));
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem); public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}3. System Provider Adaptation
After Activity replacement, the app still fails because the SettingsProvider performs package‑name and UID checks during startup. In Android O, 分身大师 hooked AMS’s getProvider and replaced the mProviderMap to bypass the check. In Android P the provider is obtained earlier, before the hook, causing verification errors.
The Settings.Global class retrieves the provider via NameValueCache.getProvider:
public IContentProvider getProvider(ContentResolver contentResolver) {
synchronized (mLock) {
if (mContentProvider == null) {
mContentProvider = contentResolver.acquireProvider(mUri.getAuthority());
}
return mContentProvider;
}
}Clearing the cached IContentProvider in ContentProviderHolder forces a re‑acquisition after the hook is in place, allowing the substituted provider to be used.
Conclusion
Android P refactors the framework layer, using ClientTransactionHandler to manage ClientTransactionItem and control the Activity lifecycle.
SettingsProvider is fetched earlier; to replace it via Binder hook, the previously obtained IContentProvider must be cleared.
With these adaptations, 分身大师 now supports dual‑open for WeChat, QQ and other major apps on Android P, with more apps in progress.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qizhuo Club
360 Mobile tech channel sharing practical experience and original insights from 360 Mobile Security and other teams across Android, iOS, big data, AI, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
