android Activity启动流程(1)

/ android / 没有评论 / 974浏览

用到的代码文件

frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/ActivityManagerNative.java
frameworks/base/core/java/android/os/Binder.java

frameworks/base/core/jni/android_util_Binder.cpp
frameworks/native/include/binder/BpBinder.h
frameworks/native/libs/binder/BpBinder.cpp
frameworks/native/libs/binder/IPCThreadState.cpp

代码执行流程图

alt

查看原图

模块编译

mm frameworks/base 编译生成system/framework/framework.jar
mm frameworks/base/core/jni/ 编译生成system/lib/libandroid_runtime.so
mm frameworks/native/libs/binder 编译生成system/lib/libbinder.so

android activity启动流程

下面的代码是以android N(api 24)为基础来进行流程分析。

本文是我记录在android launcher上启动一个activity的流程。
activity不同启动方式的启动流程不一样,此文仅作其中的一种。

当我点击launcher中某一个应用图标时,进入的是Activity中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 {
        /*
          * 上面的方法中传入的null,所以此时的逻辑走这里
          */
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

public void startActivityForResult(@RequiresPermission Intent intent, 
          int requestCode) {
    startActivityForResult(intent, requestCode, null);
}

 /*
  * 此时这个方法接受的参数 requestCode = -1, options = null;
  */
public void startActivityForResult(@RequiresPermission Intent intent, 
        int requestCode,@Nullable Bundle options) {
     /*
      * mParent == null 为true
      */
    if (mParent == null) {
         /*
          * 下面是我自己添加的log输出:
          * this:
          * 指的是启动某个activity的activity,如launcher:com.tct.launcher.Launcher
          *
          * mMainThread -> ActivityThread
          * mToken ->  android.os.BinderProxy
          *
          * intent:
          * Intent { act=android.intent.action.MAIN 
          * cat=[android.intent.category.LAUNCHER]
          * flg=0x10200000 
          * cmp=com.jrdcom.filemanager/.activity.
          *     FileBrowserActivity (has extras) }
          *
          * requestCode ->  -1
          *
          * options:
          * Bundle[{android.activity.launchStackId=-1, 
          * android:activity.animHeight=81, 
          * android.activity.launchTaskId=-1,
          * android:activity.animStartX=360, 
          * android:activity.animStartY=633, 
          * android.activity.taskOverlay=false,
          * android:activity.dockCreateMode=0, 
          * android:activity.animType=11, 
          * android:activity.animWidth=81}]
          *
          * mInstrumentation.execStartActivity调用这个方法只返回null
          */
        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 {
        Log.w("tuzhao activity","mParent == null false");
        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);
        }
    }
}

在startActivityForResult方法中最终调用的是Instrumentation类中execStartActivity()方法。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    android.util.SeempLog.record_str(377, intent.toString());
    /*
      * whoThread ->  android.app.ActivityThread$ApplicationThread
      * referrer ->  null
      */
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    ......
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        /*
          * ActivityManagerNative.getDefault():
          * android.app.ActivityManagerProxy
          * 
          * 是定义在ActivityManagerNative.java中的一个内部
          * 类,实现了IActivityManager接口
          */
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        Log.w("tuzhao Instrumentation","startActivity result ->  "+result);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

在execStartActivity()方法中最终调用的是ActivityManagerProxy类中startActivity方法。并且可以看见准备使用Binder发送消息,进程间通信。

public int startActivity(IApplicationThread caller, String callingPackage, 
        Intent intent,String resolvedType, IBinder resultTo, String resultWho, 
        int requestCode,int startFlags, ProfilerInfo profilerInfo, 
        Bundle options) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    data.writeString(callingPackage);
    intent.writeToParcel(data, 0);
    data.writeString(resolvedType);
    data.writeStrongBinder(resultTo);
    data.writeString(resultWho);
    data.writeInt(requestCode);
    data.writeInt(startFlags);
    if (profilerInfo != null) {
        data.writeInt(1);
        profilerInfo.writeToParcel(data, 
            Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    } else {
        data.writeInt(0);
    }
    if (options != null) {
        data.writeInt(1);
        options.writeToParcel(data, 0);
    } else {
        data.writeInt(0);
    }
    /*
      * mRemote ->  android.os.BinderProxy
      */
    mRemote.transact(START_ACTIVITY_TRANSACTION, 
        data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

mRemote.transact()实际上调用的是BinderProxy中的transact()方法。
BinderProxy是定义在Binder中的内部类,实现了IBinder接口。

public boolean transact(int code, Parcel data, Parcel reply, int flags) 
    throws RemoteException {
    Binder.checkParcel(this, code, data, 
        "Unreasonably large binder buffer");
    if (Binder.isTracingEnabled()) { 
      Binder.getTransactionTracker().addTrace(); 
    }
    return transactNative(code, data, reply, flags);
}

上面的方法会调用android_util_Binder.cpp中的android_os_BinderProxy_transact方法 。

// throws RemoteException
static jboolean android_os_BinderProxy_transact(JNIEnv* env, 
    jobject obj,jint code, jobject dataObj, jobject replyObj, jint flags) 
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }

    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", 
            "Binder has been finalized!");
        return JNI_FALSE;
    }

    bool time_binder_calls;
    int64_t start_millis;
    if (kEnableBinderSample) {
        // Only log the binder call duration for things on 
        // the Java-level main thread.
        // But if we don't
        time_binder_calls = should_time_binder_calls();

        if (time_binder_calls) {
            start_millis = uptimeMillis();
        }
    }

    status_t err = target->transact(code, *data, reply, flags);

    if (kEnableBinderSample) {
        if (time_binder_calls) {
            conditionally_log_binder_call(start_millis, target, code);
        }
    }

    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }

    signalExceptionForError(env, obj, err, 
        true /*canThrowRemoteException*/, data->dataSize());
    return JNI_FALSE;
}

上面方法中target->transact调用的就是BpBinder的transact方法。

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        /**
          * 这里调用的是IPCThreadState的transact方法
          */
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

最终通过Binder driver进行进程间通信。(driver这块儿就不往下追踪了。)