android Activity启动流程(3)

/ android / 没有评论 / 1085浏览

用到的代码文件

frameworks/base/core/java/android/app/ApplicationThreadNative.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/Activity.java

代称执行流程图

android activity 查看原图

android activity启动流程

下面的代码是以android N(api 24)为基础。

承接上文android Activity启动流程(2)

当ApplicationThreadProxy类的schedulePauseActivity方法通过Binder通信方式发送消息后,ApplicationThreadNative类的onTransact()方法接收到消息。

下面是ApplicationThreadNative类中onTransact()方法内容。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
    {
        android.util.Log.d(MTAG, 
            "onTransact: case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION");
        data.enforceInterface(IApplicationThread.descriptor);
        IBinder b = data.readStrongBinder();
        boolean finished = data.readInt() != 0;
        boolean userLeaving = data.readInt() != 0;
        int configChanges = data.readInt();
        boolean dontReport = data.readInt() != 0;
        /*
          * 这个是定义在IApplicationThread接口中的抽象方法。
          */
        schedulePauseActivity(b, finished, userLeaving, 
              configChanges, dontReport);
        return true;
    }
    ......
    }
    ....
}

ApplicationThread继承自ApplicationThreadNative类。
ApplicationThread是定义在ActivityThread中的内部类。
下面schedulePauseActivity()方法即是对该抽象方法的具体实现。

public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    log("method called schedulePauseActivity();");
    int seq = getLifecycleSeq();
    log("pauseActivity " + ActivityThread.this
            + " operation received seq: " + seq);
    /*pauseActivity android.app.ActivityThread@
       a9813eb operation received seq: 0*/
    /*
      *  构造一个消息,具体是在类H中进行处理。
      */
    sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? USER_LEAVING : 0) 
            | (dontReport ? DONT_REPORT : 0),
            configChanges,
            seq);
}

class H extends Handler{},下面是handleMessage()方法的具体内容。

public void handleMessage(Message msg) {
    switch (msg.what) {
        ......
        case PAUSE_ACTIVITY: {
            log("handler case PAUSE_ACTIVITY");
            Trace.traceBegin(
                Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
            SomeArgs args = (SomeArgs) msg.obj;
            //执行该方法
            handlePauseActivity((IBinder) args.arg1, false,
                    (args.argi1 & USER_LEAVING) != 0, args.argi2,
                    (args.argi1 & DONT_REPORT) != 0, args.argi3);
            maybeSnapshot();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        ......
    }
}

接下来调用ActivityThread类中的handlePauseActivity()方法,下面是具体内容。

private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, 
        boolean dontReport, int seq) {
    log("method called handlePauseActivity()");
    log("token: "+token);//token: android.os.BinderProxy@17acb46
    log("finished: "+finished);//finished: false
    log("userLeaving: "+userLeaving);//true
    log("configChanges: "+configChanges);//0
    log("dontReport: "+dontReport);//false
    log("seq: "+seq);//0
    ActivityClientRecord r = mActivities.get(token);
    /*ActivityRecord{dc3591d token=android.os.BinderProxy@6e1452f 
    {com.tct.launcher/com.tct.launcher.Launcher}}*/
    log("ActivityClientRecord r: "+r);
    if (DEBUG_ORDER) 
        Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
    if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
        return;
    }
    if (r != null) {
        //Slog.v(TAG, "userLeaving=" + userLeaving 
        //    + " handling pause of " + r);
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        //进入这个方法
        performPauseActivity(token, finished, r.isPreHoneycomb(),
             "handlePauseActivity");

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                // android.app.ActivityManagerProxy
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }
}

接下来调用ActivityThread类中的performPauseActivity()方法。

final Bundle performPauseActivity(IBinder token, 
        boolean finished,
        boolean saveState, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    //调用其重载方法
    return r != null 
        ? performPauseActivity(r, finished, saveState, reason) : null;
}

下面进入performPauseActivity()这个重载方法的执行流程。

final Bundle performPauseActivity(ActivityClientRecord r, 
        boolean finished,
        boolean saveState, String reason) {
    log("method called performPauseActivity()");
    /*ActivityRecord{dc3591d 
    token=android.os.BinderProxy@6e1452f
     {com.tct.launcher/com.tct.launcher.Launcher}}*/
    log("ActivityClientRecord r : " + r);
    log("finished : " + finished);//false
    log("saveState : " + saveState);//false
    log("reason: " + reason);//handlePauseActivity
    if (r.paused) {
        if (r.activity.mFinished) {
            // If we are finishing, we won't call onResume()
            // in certain cases.
            // So here we likewise don't want to call
            // onPause() if the activity
            // isn't resumed.
            return null;
        }
        RuntimeException e = new RuntimeException(
                "Performing pause of activity that is not resumed: "
                + r.intent.getComponent().toShortString());
        Slog.e(TAG, e.getMessage(), e);
    }
    if (finished) {
        r.activity.mFinished = true;
    }
    //// com.tct.launcher.Launcher
    log("r.activity: " + r.activity.getClass().getName());
    // Next have the activity save its current state
    // and managed dialogs...
    if (!r.activity.mFinished && saveState) {
        callCallActivityOnSaveInstanceState(r);
    }
    /*
      * 进入这里
      */
    performPauseActivityIfNeeded(r, reason);

    // Notify any outstanding on paused listeners
    ArrayList<OnActivityPausedListener> listeners;
    synchronized (mOnPauseListeners) {
        listeners = mOnPauseListeners.remove(r.activity);
    }
    int size = (listeners != null ? listeners.size() : 0);
    for (int i = 0; i < size; i++) {
        listeners.get(i).onPaused(r.activity);
    }

    return !r.activity.mFinished && saveState ? r.state : null;
}

下面进入ActivityThread类中的performPauseActivityIfNeeded()方法。
instrumentation n. 使用仪器, 乐器化, 仪表化, 指令

private void performPauseActivityIfNeeded(ActivityClientRecord r,
     String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }

    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, 
                 UserHandle.myUserId(),
                r.activity.getComponentName().getClassName(),
                 reason);
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " 
                    + safeToComponentShortString(r.intent)
                    + " 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 "
                    + safeToComponentShortString(r.intent) + ": " 
                    + e.toString(), e);
        }
    }
    r.paused = true;
}

下面调用Instrumentation类中的callActivityOnPause()方法。

/**
 * Perform calling of an activity's 
 * {@link Activity#onPause} method.  The
 * default implementation simply calls through
 * to that method.
 *
 * @param activity The activity being paused.
 */
public void callActivityOnPause(Activity activity) {
    //调用了Activity自身的performPause方法
    activity.performPause();
}

下面是Activity类中performPause()方法的具体内容。

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    /**
      * 找到了一个生命周期方法onPause()
      * 表明我们在启动一个Activity的时候最先
      * 被执行的是当前的Activity的onPause方法。
      */
    onPause();
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    mResumed = false;
}

在ActivityThread类的handlePauseActivity()方法中执行完performPauseActivity()方法后将会进入下面的流程。

private void handlePauseActivity(IBinder token, 
        boolean finished,boolean userLeaving, 
        int configChanges, boolean dontReport, 
        int seq) {
        ......
        //这步暂停指定Activity已经结束了。
        performPauseActivity(token, 
            finished, r.isPreHoneycomb(), "handlePauseActivity");
        ......
        // Tell the activity manager we have paused.
        if (!dontReport) {// dontReport -> false
            try {
                /**
                  * 关键的是这里,继续往下追踪。
                  */
                ////android.app.ActivityManagerProxy
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }
}

ActivityManagerProxy类是定义在ActivityManagerNative中的一个内部类。
下面是ActivityManagerProxy类中activityPaused()方法的具体实现。

public void activityPaused(IBinder token) throws RemoteException
{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(token);
    mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

又调用Binder了,又进行进程间通信了......