Android P ActivityManagerService(三) startActivity的第一小部分

从Activity的启动流程来窥探AMS;

由于启动流程比较长,准备拆分之后细细品尝;

Activity.java中的startActivity;

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

options参数大多数情况下都是null;在Context.java对这个参数的相应的解释;

如下:

@param options Additional options for how the Activity should be started.
May be null if there are no options.  See {@link android.app.ActivityOptions}
for how to build the Bundle supplied here; there are no supported definitions
for building it manually.

这个Bundle有自己固有内容——ActivityOptions;大体浏览之后会发现里面都是一些关于动画之类的东西;由于和启动流程关系不是特别密切,这里暂不展开;

Activity.java中的startActivityForResult;

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

一般来说,我们的Activity不会被包含在另一个Activity中,特别是大家早已习惯Fragment之后;故mParent一般都是null;我们暂时先关注mParent为空的情况;

主要涉及以下几个步骤:

  • transferSpringboardActivityOptions用来在options用空时获取options;
  • Instrumentation的execStartActivity方法是启动的关键;
  • ActivityThread的sendActivityResult方法;
  • cancelInputsAndStartExitTransition

transferSpringboardActivityOptions

private Bundle transferSpringboardActivityOptions(Bundle options) {
    if (options == null && (mWindow != null && !mWindow.isActive())) {
        final ActivityOptions activityOptions = getActivityOptions();
        if (activityOptions != null &&
                activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
            return activityOptions.toBundle();
        }
    }
    return options;
}
/**
 * Retrieve the ActivityOptions passed in from the launching activity or passed back
 * from an activity launched by this activity in its call to {@link
 * #convertToTranslucent(TranslucentConversionListener, ActivityOptions)}
 *
 * @return The ActivityOptions passed to {@link #convertToTranslucent}.
 * @hide
 */
ActivityOptions getActivityOptions() {
    try {
        return ActivityOptions.fromBundle(
                ActivityManager.getService().getActivityOptions(mToken));
    } catch (RemoteException e) {
    }
    return null;
}

这部分代码主要是针对Activity切换动画部分的;

Instrumentation的execStartActivity方法

先看下Instrumentation的名字解释;

/**
 * Base class for implementing application instrumentation code.  When running
 * with instrumentation turned on, this class will be instantiated for you
 * before any of the application code, allowing you to monitor all of the
 * interaction the system has with the application.  An Instrumentation
 * implementation is described to the system through an AndroidManifest.xml's
 * <instrumentation> tag.
 */

也就是说Instrumentation其实是个测试辅助类;

execStartActivity参数:

  • who 调用startActivity的Context;
  • contextThread 调用startActivity的Context的主线程;
  • token 内部token让系统辨认谁启动了activity;可能为空;
  • target 启动和接收result的activity;当非activity启动时,可能为空;
  • intent 启动时的intent;
  • requestCode 大家都懂的;不存在的话设置小于0即可;源码是传入-1;
  • options 附加选项;
  • 返回值ActivityResult 要强制返回时,会返回一个包含所需数据的ActivityResult,否则返回空 ;基本都返回空;
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                ActivityResult result = null;
                if (am.ignoreMatchingSpecificIntents()) {
                    result = am.onStartActivity(intent);
                }
                if (result != null) {
                    am.mHits++;
                    return result;
                } else if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
  • Uri referrer;默认返回是空的;

如下:

/**
 * Override to generate the desired referrer for the content currently being shown
 * by the app.  The default implementation returns null, meaning the referrer will simply
 * be the android-app: of the package name of this activity.  Return a non-null Uri to
 * have that supplied as the {@link Intent#EXTRA_REFERRER} of any activities started from it.
 */
public Uri onProvideReferrer() {
    return null;
}

可以重写这个方法,类似:

@Override
public Uri onProvideReferrer() {
    return Uri.parse("http://www.example.com/VoiceInteractionMain");
}

这个Uri会以参数(Intent.EXTRA_REFERRER)的形式传给被这个Activity启动Activity;

但这样做具体有什么用呢?!

这种设计目的是什么?!

有什么好处?!

不明白!!!

  • mActivityMonitors相关的一溜代码都是和调试测试相关的,这里不做讨论;
  • ActivityManager.getService().startActivity;这个方法负责实际的启动工作;

ActivityManager的getService获取到IActivityManager;其实就是AMS;这块内容在之前已经提到过了;

AMS中的处理放下后面详细讨论;

  • checkStartActivityResult检查返回值,抛出各种异常,如常见的ActivityNotFoundException;
/** @hide */
public static void checkStartActivityResult(int res, Object intent) {
    if (!ActivityManager.isStartResultFatalError(res)) {
        return;
    }

    switch (res) {
        case ActivityManager.START_INTENT_NOT_RESOLVED:
        case ActivityManager.START_CLASS_NOT_FOUND:
            if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                throw new ActivityNotFoundException(
                        "Unable to find explicit activity class "
                        + ((Intent)intent).getComponent().toShortString()
                        + "; have you declared this activity in your AndroidManifest.xml?");
            throw new ActivityNotFoundException(
                    "No Activity found to handle " + intent);
        case ActivityManager.START_PERMISSION_DENIED:
            throw new SecurityException("Not allowed to start activity "
                    + intent);
        case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
            throw new AndroidRuntimeException(
                    "FORWARD_RESULT_FLAG used while also requesting a result");
        case ActivityManager.START_NOT_ACTIVITY:
            throw new IllegalArgumentException(
                    "PendingIntent is not an activity");
        case ActivityManager.START_NOT_VOICE_COMPATIBLE:
            throw new SecurityException(
                    "Starting under voice control not allowed for: " + intent);
        case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
            throw new IllegalStateException(
                    "Session calling startVoiceActivity does not match active session");
        case ActivityManager.START_VOICE_HIDDEN_SESSION:
            throw new IllegalStateException(
                    "Cannot start voice activity on a hidden session");
        case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
            throw new IllegalStateException(
                    "Session calling startAssistantActivity does not match active session");
        case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
            throw new IllegalStateException(
                    "Cannot start assistant activity on a hidden session");
        case ActivityManager.START_CANCELED:
            throw new AndroidRuntimeException("Activity could not be started for "
                    + intent);
        default:
            throw new AndroidRuntimeException("Unknown error code "
                    + res + " when starting " + intent);
    }
}

ActivityThread的sendActivityResult方法

先看一下ActivityThread的名词解释;这个是类似一个小管家的角色;继承了ClientTransactionHandler;

/**
 * This manages the execution of the main thread in an
 * application process, scheduling and executing activities,
 * broadcasts, and other operations on it as the activity
 * manager requests.
 *
 * {@hide}
 */
public final class ActivityThread extends ClientTransactionHandler

sendActivityResult方法;

/** @hide */
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
    }
}

ClientTransaction的名词解释;

/**
 * A container that holds a sequence of messages, which may be sent to a client.
 * This includes a list of callbacks and a final lifecycle state.
 *
 * @see com.android.server.am.ClientLifecycleManager
 * @see ClientTransactionItem
 * @see ActivityLifecycleItem
 * @hide
 */
public class ClientTransaction implements Parcelable, ObjectPoolItem

addCallback在序列的最后添加一个消息;

/**
 * Add a message to the end of the sequence of callbacks.
 * @param activityCallback A single message that can contain a lifecycle request/callback.
 */
public void addCallback(ClientTransactionItem activityCallback) {
    if (mActivityCallbacks == null) {
        mActivityCallbacks = new ArrayList<>();
    }
    mActivityCallbacks.add(activityCallback);
}

ApplicationThread是ActivityThread的一个内部类;它的scheduleTransaction方法最后还是会调用ActivityThread的scheduleTransaction方法;

private class ApplicationThread extends IApplicationThread.Stub 
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

ActivityThread的scheduleTransaction方法来自于它的父类ClientTransactionHandler;

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

ActivityThread的内部类H;

class H extends Handler

其中处理EXECUTE_TRANSACTION部分的代码;

case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    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.

TransactionExecutor的名词解释;

/**
 * Class that manages transaction execution in the correct order.
 * @hide
 */
public class TransactionExecutor
/**
 * Resolve transaction.
 * First all callbacks will be executed in the order they appear in the list. If a callback
 * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
 * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
 * either remain in the initial state, or last state needed by a callback.
 */
public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}

executeCallbacks,遍历callback序列,然后逐个执行;

/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null) {
        // No callbacks to execute, return early.
        return;
    }
    log("Resolving callbacks");

    final IBinder token = transaction.getActivityToken();
    ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    // In case when post-execution state of the last callback matches the final state requested
    // for the activity in this transaction, we won't do the last transition here and do it when
    // moving to final state instead (because it may contain additional parameters from server).
    final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
    final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
            : UNDEFINED;
    // Index of the last callback that requests some post-execution state.
    final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        log("Resolving callback: " + item);
        final int postExecutionState = item.getPostExecutionState();
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                item.getPostExecutionState());
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState);
        }

        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        if (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;
            cycleToPath(r, postExecutionState, shouldExcludeLastTransition);
        }
    }
}

这里的关键是item.execute(mTransactionHandler, token, mPendingActions);

ClientTransactionItem的execute方法;

@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
    client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

ClientTransactionHandler的handleSendResult方法;

ClientTransactionHandler是个抽象类,handleSendResult是它的抽象方法;

TransactionExecutor的构造方法中,会将ClientTransactionHandler作为参数传入;

ActivityThread中初始化TransactionExecutor时,将ActivityThread本身传入;

而之前就提到过ActivityThread继承了ClientTransactionHandler;

// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

因此,在ActivityThread寻找handleSendResult方法;

@Override
public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
    if (r != null) {
        final boolean resumed = !r.paused;
        if (!r.activity.mFinished && r.activity.mDecor != null
                && r.hideForNow && resumed) {
            // We had hidden the activity because it started another
            // one...  we have gotten a result back and we are not
            // paused, so make sure our window is visible.
            updateVisibility(r, true);
        }
        if (resumed) {
            try {
                // Now we are idle.
                r.activity.mCalled = false;
                r.activity.mTemporaryPause = true;
                mInstrumentation.callActivityOnPause(r.activity);
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString()
                        + " did not call through to super.onPause()");
                }
            } catch (SuperNotCalledException e) {
                throw e;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to pause activity "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
                }
            }
        }
        checkAndBlockForNetworkAccess();
        deliverResults(r, results, reason);
        if (resumed) {
            r.activity.performResume(false, reason);
            r.activity.mTemporaryPause = false;
        }
    }
}

deliverResults;

private void deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason) {
    final int N = results.size();
    for (int i=0; i<N; i++) {
        ResultInfo ri = results.get(i);
        try {
            if (ri.mData != null) {
                ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
                ri.mData.prepareToEnterProcess();
            }
            if (DEBUG_RESULTS) Slog.v(TAG,
                    "Delivering result to activity " + r + " : " + ri);
            r.activity.dispatchActivityResult(ri.mResultWho,
                    ri.mRequestCode, ri.mResultCode, ri.mData, reason);
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Failure delivering result " + ri + " to activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
            }
        }
    }
}

最终会调用r.activity.dispatchActivityResult;

查看Activity的dispatchActivityResult方法;

好吧,兜兜转转一圈,又回到了Activity.java;这里会调用各个Case下onActivityResult;

void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data,
            String reason) {
    if (false) Log.v(
        TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
        + ", resCode=" + resultCode + ", data=" + data);
    mFragments.noteStateNotSaved();
    if (who == null) {
        onActivityResult(requestCode, resultCode, data);
    } else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) {
        who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length());
        if (TextUtils.isEmpty(who)) {
            dispatchRequestPermissionsResult(requestCode, data);
        } else {
            Fragment frag = mFragments.findFragmentByWho(who);
            if (frag != null) {
                dispatchRequestPermissionsResultToFragment(requestCode, data, frag);
            }
        }
    } else if (who.startsWith("@android:view:")) {
        ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
                getActivityToken());
        for (ViewRootImpl viewRoot : views) {
            if (viewRoot.getView() != null
                    && viewRoot.getView().dispatchActivityResult(
                            who, requestCode, resultCode, data)) {
                return;
            }
        }
    } else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
        Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
        getAutofillManager().onAuthenticationResult(requestCode, resultData, getCurrentFocus());
    } else {
        Fragment frag = mFragments.findFragmentByWho(who);
        if (frag != null) {
            frag.onActivityResult(requestCode, resultCode, data);
        }
    }
    writeEventLog(LOG_AM_ON_ACTIVITY_RESULT_CALLED, reason);
}

cancelInputsAndStartExitTransition

最后一个方法,光看注释就很明了了;

/**
 * Cancels pending inputs and if an Activity Transition is to be run, starts the transition.
 *
 * @param options The ActivityOptions bundle used to start an Activity.
 */
private void cancelInputsAndStartExitTransition(Bundle options) {
    final View decor = mWindow != null ? mWindow.peekDecorView() : null;
    if (decor != null) {
        decor.cancelPendingInputEvents();
    }
    if (options != null && !isTopOfTask()) {
        mActivityTransitionState.startExitOutTransition(this, options);
    }
}

小结

Instrumentation 一个辅助测试类,启动Activity时通过它来调用AMS中的启动方法;
ActivityThread

主线程的小管家,继承自ClientTransactionHandler;

onActivityResult就是通过它来实现的;

ApplicationThread

ActivityThread的一个内部类,暂时还没做什么惊天动地的大事情;

但有个关键点,它实现了IBinder接口,能进行进程间通讯;

  • 第一小部分暂不涉及AMS里面内容,相对简答明了;
  • TransactionExecutor、ClientTransactionHandler、ClientTransaction 、ClientTransactionItem的消息机制很好玩;
  1. TransactionExecutor负责按照顺序执行ClientTransaction内的ClientTransactionItem序列;持有ClientTransactionHandler对象;
  2. ClientTransactionHandler定义消息执行时真正进行的操作;抽象类,需要人继承;这里ActivityThread继承了它;
  3. ClientTransaction一个持有一系列消息的容器,可以发送给客户端,包括ClientTransactionItem列表和ActivityLifecycleItem;
  4. ClientTransactionItem消息本身;抽象类,需要人继承;这里ActivityResultItem继承了它;
  5. ActivityLifecycleItem请求活动应达到的生命周期状态;抽象类,需要人继承;这里没讨论到;

TransactionExecutor的execute方法会把ClientTransaction作为参数传入;

这样就把消息和处理消息的操作关联了起来;

猜你喜欢

转载自blog.csdn.net/weixin_39821531/article/details/89360486