android-App启动过程

前言

APP启动流程涉及的类和调用的方法还是蛮多的,做为android应用开发其实知道整个流程和重要的调用方法就够了。但是在了解整个流程前,得先知道涉及的相关知识,这样才能更好理解后面整个流程。后面源码分析基于Android-2.2_r1。

Zygote

zygote名字翻译叫受精卵,首先要知道zygote进程的创建是由Linux系统中init进程创建的,Android中所有的进程都是直接或者间接的由init进程fork出来的,Zygote进程负责其他进程的创建和启动,比如创建SystemServer进程。当需要启动一个新的android应用程序的时候,ActivityManagerService就会通过Socket通知Zygote进程为这个应用创建一个新的进程

Launcher

我们要知道手机的桌面也是一个App我们叫它launcher,每一个手机应用都是在Launcher上显示,而Launcher的加载是在手机启动的时候加载Zygote,然后Zygote启动SystenServer,SystenServer会启动各种ManageService, 包括ActivityManagerService,并将这些ManageService注册到ServiceManage 容器中,然后ActivityManagerService就会启动Home应用程序Launcher.

ActivityManagerService

ActivityManagerService我们简称AMS,首先当我们看到名字的时候,我们以为他是管理Activity的,其实四大组件都归它管,四大组件的跨进程通信都要和它合作,后面讲Binder时候会提到它。
AMS管理Activity主要是管理什么呢? 这就要说到AMS的相关类:

  • ProcessRecord 表示应用进程记录,每个应用进程都有对应的ProcessRecord对象
  • ActivityStack 该类主要管理回退栈
  • ActviityRecord 每次启动一个Activity会有一个对应的ActivityRecord对象,表示一个Activity的一个记录
  • ActivityInfo Activity信息,比如启动模式,taskAffinity,flag信息
  • TaskRecord Task记录信息,一个Task可能有多个ActivityRecord,但是一个ActivityRecord只能属于一个TaskRecord

Binder

Binder是Android跨进程通信(IPC)的一种方式,也是Android系统中最重要的特性之一,android 四大组件以及不同的App都运行在不同的进程,它则是各个进程的桥梁将不同的进程粘合在一起。
学习Binder首先要知道相关客户端、服务端的概念,然后去把AIDL弄透彻, 知道系统生成的Aidl Java文件中每一个类所代表的是什么角色,然后看源码,能将ActivityManageService 用来跨进程同通信中各个角色弄明白就算是理解了,不过这只是一部分部分,得多总结归纳。

ActivityThread

首先ActivityThread并不是一个Thread,其作用就是在main方法内做消息循环。那我们常说的主线程是什么?主线程就是承载ActivityThreadZygote fork而创建的进程 ,这里可能有人会不能理解进程和线程的区别,这里不详细讲述自行学习。ActivityThread的调用是在ActivityManageService.startProcessLocked()方法里调用并创建,这个类主要做了这几个事

  1. 创建Looper,开启Looper循环
  2. 创建内部类 H,H继承于Handler 用于跨进程通信切换线程
  3. 创建ApplicationThread跨进程Binder对象mAppThread。 这里要说一点,ActivityThread通过ApplicationThread与AMS进行通信,ApplicationThread通过H与ActivityThread进行通信(handler机制),处理Activity的事务

启动方式
app的启动我们将其分为两种:

  1. 冷启动:当应用启动的时候,后台没有当前应用的进程,这时系统会创建一个新的进程分配给应用。
  2. 热启动:当前应用已经打开,但是被按下返回键或者Home键退出到桌面或者去到其他App,当再次回到应用时就是热启动。
    这里我们主要介绍冷启动过程,首先简单介绍下冷启动的的整个流程,然后再根据关键代码讲解。

App启动5步走

借用GITYUAN大神的一张图结合启动App逻辑讲一下App启动的整个流程,不过这是一张Launcher App启动的图,和我们要说的有点不一样,我们根据老罗所说的将App启动分为5步

  1. Launcher通过Binder进程间通信机制通知ActivityManagerService,
    它要启动一个Activity;
  2. ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
  3. Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态, 于是ActivityManagerServicey利用Zygote.fork()创建一个新的进程,用来启动一个ActivityThread实例, 即将要启动的Activity就是在这个ActivityThread实例中运行;
  4. ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,
    以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
  5. ActivityManagerService通过Binder进程间通信机制通知ActivityThread,
    现在一切准备就绪,它可以真正执行Activity的启动操作了。

在这里插入图片描述

第一步1-3

Launcher的点击监听
首先我们在物理上点击了手机屏幕上的App快捷键图标,这里Launcher是这么操作的呢?我看位于android.launcher2下的源码Launcher

1、 这里可以看到,Launcher继承于Activity,并在其onClick()事件中监听了app的图标点击,调用了Launcher的startActivitySafely()方法


public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
...

 /**
     * Launches the intent referred by the clicked shortcut.
     *
     * @param v The view representing the clicked shortcut.
     */
    public void onClick(View v) {
        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            // Open shortcut
            final Intent intent = ((ShortcutInfo) tag).intent;
            int[] pos = new int[2];
            v.getLocationOnScreen(pos);
            intent.setSourceBounds(new Rect(pos[0], pos[1],
                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));
            startActivitySafely(intent, tag);
        } else if (tag instanceof FolderInfo) {
            handleFolderClick((FolderInfo) tag);
        } else if (v == mHandleView) {
            if (isAllAppsVisible()) {
                closeAllApps(true);
            } else {
                showAllApps(true);
            }
        }
    }
...

}

2、这里将这个启动方式使用Intent.FLAG_ACTIVITY_NEW_TASK, 创建了一个新的TASK栈,然后继续调用父类ActivitystartActivity()方法

 void startActivitySafely(Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        } catch (SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
                    "or use the exported attribute for this activity. "
                    + "tag="+ tag + " intent=" + intent, e);
        }
    }

3、Activity的startActivity()方法中传递了默认为-1requestCode,表示不需要返回值,然后调用了startActivityForResult(),在这个方法中我们看到一个mInstrumentation变量,这个变量是Instrumentation对象的实例,具体是在Activity的attach()方法中进行赋值的。然后startActivityForResult()方法中调用了mInstrumentation.execStartActivity()方法,然后在其中传递了两个参数我们要介绍下,

  • mMainThread.getApplicationThread():mMainThread变量声明是 ActivityThread对象,而getApplicationThread()方法则返回的是ApplicationThread的实例。
  • mToken :的声明为 private IBinder mToken;
    这里为什么传递这两个参数我们后面说,我们继续看execStartActivity()方法。
 @Override
    public void startActivity(Intent intent) {
        startActivityForResult(intent, -1);
    }
public void startActivityForResult(Intent intent, int requestCode) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode);
            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;
            }
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }

第二步4-7

4、我们继续看位于android/app/Instrumentation.java中的execStartActivity方法,最后调用了ActivityManagerNative.getDefault().startActivity()方法,就要和AMS进行Binder的ICP通信了,AMS会收到startActivity的请求,执行startActivity()方法。

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode) {
      IApplicationThread whoThread = (IApplicationThread) contextThread;
      if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i = 0; i < N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        int result = ActivityManagerNative.getDefault().startActivity(whoThread, intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token,
            target != null ? target.mEmbeddedID : null, requestCode, false, false);
        checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}

5、首先我们知道Launcher本来就是一个Activity,并单独处于一个进程中,现在要启动另一个我们所点击的APP的Activity,而AMS是管理所有Activity的,那么我们就会和AMS使用Binder进行跨进程通信。
这里我们也具体了解下是谁和AMS进行跨进程通信?
使用Binder进行通信,就首先得有Server进程和Client进程,
首先Server会提供一套接口函数供Client调用,这个时候通常会采用Proxy设计模式。将接口定义在一个抽象类中,Server和Client都会以该抽象类为基础实现所有函数。 而在Client端会具有Server端的代理对象Proxy,Proxy具有和Server一样的方法,Client使用代理对象经过Binder的转换,跨进程调用Server的服务。具体理解这一块先看看AIDl相关。

再回到步骤4 的ActivityManagerNative.getDefault().startActivity()方法,这个方法后面调用asInterface()然后返回ActivityManagerProxy对象,这个对象其实就是AMS在客户端的代理对象,ActivityManagerProxy实现IActivityManager接口,具有AMS所提供的方法,不同的是,ActivityManagerProxy并没有实现方法,ActivityManagerProxy只是将客服端发起的请求进行参数进行打包封装,并在每一个方法中添加唯一表示,然后将请求发送到Binder,Binder就会将请求转发给server,server根据唯一表示调用相应的server的相关方法
再看下AMS:AMS继承了ActivityManagerNative同样实现了IActivityManager接口。这里就能

也就是说与AMS通信的其实是AMS的代理对象ActivityManagerProxy,通过:ActivityManagerProxy -> Binder驱动 -> AMS

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {}

public abstract class ActivityManagerNative extends Binder implements IActivityManager{}

class ActivityManagerProxy implements IActivityManager{}


private final class ApplicationThread extends ApplicationThreadNative {}
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
。。。
 static public IActivityManager getDefault()
    {
      ...
        IBinder b = ServiceManager.getService("activity");
        if (Config.LOGV) Log.v(
            "ActivityManager", "default service binder = " + b);
        gDefault = asInterface(b);
      ...
        return gDefault;
    }


 static public IActivityManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ActivityManagerProxy(obj);
    }

class ActivityManagerProxy implements IActivityManager{}
...
}

在这里插入图片描述

6、Activity通过Binder将消息传递到了AMS,AMS的startActivity()方法接收到方法开始一系列的调用,这里整个AMS会做几个操作

  1. 对参数intent的内容进行解析,保存到ResolveInfo对象中
  2. 从传进来的参数得到调用者的进程信息,保存到ProcessRcord对象中,这里获取的就是Launcher应用程序的进程
  3. 创建即将要启动的Activity的相关信息 保存到ActivityRecord对象
  4. 根据intent的参数设置启动模式,并创建一个新的Task来启动这个Activity
  5. 将创建的Task保存到ActivityManagerService
  6. 将Launcher推入Paused状态
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {

...

	public final int startActivity(IApplicationThread caller,
            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
            int grantedMode, IBinder resultTo,
            String resultWho, int requestCode, boolean onlyIfNeeded,
            boolean debug) {
        return startActivityMayWait(caller, intent, resolvedType,
                grantedUriPermissions, grantedMode, resultTo, resultWho,
                requestCode, onlyIfNeeded, debug, null, null);
    }

 private final int startActivityMayWait(IApplicationThread caller,
            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
            int grantedMode, IBinder resultTo,
            String resultWho, int requestCode, boolean onlyIfNeeded,
            boolean debug, WaitResult outResult, Configuration config) {
...
  int res = startActivityLocked(caller, intent, resolvedType,
                    grantedUriPermissions, grantedMode, aInfo,
                    resultTo, resultWho, requestCode, callingPid, callingUid,
                    onlyIfNeeded, componentSpecified);
...
}
// 调用到startActivityUncheckedLocked的时候就说明要启动的Activity已经通过检查,被认为是一个正当的启动请求
 private final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType,
            Uri[] grantedUriPermissions,
            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, boolean onlyIfNeeded,
            boolean componentSpecified) {

  return startActivityUncheckedLocked(r, sourceRecord,
                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
}
private final int startActivityUncheckedLocked(HistoryRecord r,
            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
...
  startActivityLocked(r, newTask, doResume);
        return START_SUCCESS;
...
}
//
 private final void startActivityLocked(HistoryRecord r, boolean newTask,
            boolean doResume) {
...
if (doResume) {
            resumeTopActivityLocked(null);
        }
...
}
//
 private final boolean resumeTopActivityLocked(HistoryRecord prev) {
...
if (mResumedActivity != null) {
            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
            startPausingLocked(userLeaving, false);
            return true;
        }
...
}

7、AMS处理完Activity相关设置后,调用prev.app.thread.schedulePauseActivity()方法, 这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。schedulePauseActivity方法定义在 IApplicationThread.java 文件中
到这里,AMS通知Launcher要启动一个Activity,Launcher也要进入到Paused了,后面也会用到我们第3步中的token。

 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
...
   if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        System.identityHashCode(prev),
                        prev.shortComponentName);
                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
                        prev.configChangeFlags);
                updateUsageStats(prev, false);
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
        }

...
}
...

}

第三步 8-12

8、这里AMS又要通过Binder通知Launcher更新状态(这里要知道AMS是和ActivityThread进行通信),而AMS 是这么和 ActivityThread进行跨进程通信? 看了上面的第5步,我们知道跨进程通信总得实现同一个接口,我们再归纳下AMS和ActivityThread的进行跨进程通信。

之前我们说到ActivityThread是通过ApplicationThread与AMS进行通信的,ApplicationThread也是继承ApplicationThreadNative实现了同样的IActivityManager接口。ApplicationThreadProxy也是实现了IApplicationThread接口。
也就是说与和AMS通信是:ApplicationThreadProxy -> Binder驱动 -> ApplicationThread。

 private final class ApplicationThread extends ApplicationThreadNative {}

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {}

class ApplicationThreadProxy implements IApplicationThread {}

9、我们继续步骤7中最后调用的schedulePauseActivity()方法,这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中

class ApplicationThreadProxy implements IApplicationThread {
...
public final void schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(finished ? 1 : 0);
        data.writeInt(userLeaving ? 1 :0);
        data.writeInt(configChanges);
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
...
}
//当 finished 为false 时候,queueOrSendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher,也就是第3步传过来的mToken实例
private final class ApplicationThread extends ApplicationThreadNative {
...
 public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges) {
            queueOrSendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0),
                    configChanges);
        }
...
}

10、我们继续看queueOrSendMessage()方法,在方法看到 mH.sendMessage(msg),这个mH就是Activity中的继承于Hander的内部类H,根据handler我知道有发送就有接收,并且我们知道发送的what是H.PAUSE_ACTIVITY。

 private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            if (localLOGV) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                + ": " + arg1 + " / " + obj);
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            mH.sendMessage(msg);
        }
    }

11、继续看handler接收,在接收的地方调用了handlePauseActivity()方法,将binder引用token转换成ActivityRecord,然后做了三个事情:

  1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;
  2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;
  3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。
 private final class H extends Handler {
...

	public void handleMessage(Message msg) {
 	 switch (msg.what) {
 	case PAUSE_ACTIVITY:
                    handlePauseActivity((IBinder)msg.obj, false, 			    msg.arg1 != 0, msg.arg2);
                    maybeSnapshot();
                    break;
}
...
}

 private final void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges) {
        ActivityRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            Bundle state = performPauseActivity(token, finished, true);

            // Tell the activity manager we have paused.
            try {
                ActivityManagerNative.getDefault().activityPaused(token, state);
            } catch (RemoteException ex) {
            }
        }
    }

 final Bundle performPauseActivity(ActivityRecord r, boolean finished,
            boolean saveState) {
...
	// 调用 onPause();
	mInstrumentation.callActivityOnPause(r.activity);
...
}

12、继续看通过Binder机制调用AMS的方法, 看这个方法 ActivityManagerNative.getDefault().activityPaused(token, state)是不是感觉很熟悉了;这又是一次跨进程通信,这个方法首先会调用ActivityManagerProxy 相应的方法,然后跨进程传递到ActivityManagerService的activityPaused()方法执行,然后一路向下调用。

class ActivityManagerProxy implements IActivityManager{
...
	public void activityPaused(IBinder token, Bundle state) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        data.writeBundle(state);
        mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
...
}
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {           
...
	public final void activityPaused(IBinder token, Bundle icicle) {
        // Refuse possible leaked file descriptors
        if (icicle != null && icicle.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Bundle");
        }

        final long origId = Binder.clearCallingIdentity();
        activityPaused(token, icicle, false);
        Binder.restoreCallingIdentity(origId);
    }
...
}
final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
...
 	synchronized (this) {
          ...
                    completePauseLocked();
          ...
        }
...
}


private final void completePauseLocked() {
...
	if (!mSleeping && !mShuttingDown) {
            resumeTopActivityLocked(prev);
        } else {
        }
...
}

private final boolean resumeTopActivityLocked(HistoryRecord prev) {
...
 	startSpecificActivityLocked(next, true, true);
...
}


private final void startSpecificActivityLocked(HistoryRecord r,
            boolean andResume, boolean checkConfig) {
...
	startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false);
...
}

主要是调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,其中会根据uid+process的组合为应用创建一个ProcessRecord,并验证是否有process + uid命名的进程存在

private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
...
	int pid = Process.start("android.app.ActivityThread",
                    mSimpleProcessManagement ? app.processName : null, uid, uid,
                    gids, debugFlags, null);
...
}

第四步 13-14

13、现在AMS创建了一个进程ActivityThread,并启动这个类的main方法,先是创建一个Looper,然后调用thread.attach()方法,后面开始消息循环直到进程退出,然后一直到ActivityManageProxy的相应方法,然后通过Binder 机制向ActivityManagerService传递了一个ApplicationThread类型的Binder对象,作用是用于进程间通信。通信方式就是过程8所介绍的

public final class ActivityThread {
...
public static final void main(String[] args) {
...
	Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        Looper.loop();
...
}

 private final void attach(boolean system) {
 	IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
            }
}
...
}

class ActivityManagerProxy implements IActivityManager{
...
 public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
...
}

14、ActivityThread使用调用attachApplication()方法使用Binder机制向AMS传递了一个Application对象,AMS的接受到后调用相应的attachApplication()方法

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
...
 public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
...
}
 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
...

	try {
		if (realStartActivityLocked(hr, app, true, true)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                  
                }
...
}


//最终通过app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中
private final boolean realStartActivityLocked(HistoryRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
...
 app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
                    System.identityHashCode(r),
                    r.info, r.icicle, results, newIntents, !andResume,
                    isNextTransitionForward());

...
}

第五步15

15、AMS得到了ActivityThread的Application对象后,又个给ActivityThread发送了一个消息,调用了ApplicationThread的scheduleLaunchActivity()方法,这里我们一定要将前面讲的:AMS和ActivityThread通过ApplicationThread通信弄明白

class ApplicationThreadProxy implements IApplicationThread {
...
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
    List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
    throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(token);
        data.writeInt(ident);
        info.writeToParcel(data, 0);
        data.writeBundle(state);
        data.writeTypedList(pendingResults);
        data.writeTypedList(pendingNewIntents);
        data.writeInt(notResumed ? 1 : 0);
        data.writeInt(isForward ? 1 : 0);
        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

...
}

//然后调用到ApplicationThread的相应方法,创建一个ActivityRecord实例,并且初始化它的成员变量,然后调用ActivityThread类的queueOrSendMessage函数进一步处理。

 private final class ApplicationThread extends ApplicationThreadNative {
...
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
            ActivityRecord r = new ActivityRecord();
          r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.state = state;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }
...
}

我们之前说过,进程内存是使用Handler进行线程间调用,这里ActivityThread和ApplicationThread就是使用小H类 Handler发送了一个what为 H.LAUNCH_ACTIVITY的消息,我们再看接收的地方

 private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            if (localLOGV) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                + ": " + arg1 + " / " + obj);
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            mH.sendMessage(msg);
        }
    }

// 这里首先调用performLaunchActivity函数来加载这个Activity类,即 MainActivity,然后调用它的onCreate函数。再调用handleResumeActivity函数来使这个Activity进入Resumed状态,即会调用这个Activity的onResume函数,这是遵循Activity的生命周期的。

 private final class H extends Handler {
...
 public void handleMessage(Message msg) {
 switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    ActivityRecord r = (ActivityRecord)msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo);
                    handleLaunchActivity(r, null);
                } break;
}
}
...
}
 private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);
        Activity a = performLaunchActivity(r, customIntent);
...
}
private final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
     // 1、 收集要启动的Activity的相关信息,主要package和component信息,
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
//2、然后通过ClassLoader将shy.luo.activity.MainActivity类加载进来:
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            r.intent.setExtrasClassLoader(cl);
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
//3、创建Application对象,这是根据AndroidManifest.xml配置文件中的Application标签的信息来创建
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                ContextImpl appContext = new ContextImpl();
                appContext.init(r.packageInfo, r.token, this);
                appContext.setOuterContext(activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
//4、创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到MainActivity中去
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstance,
                        r.lastNonConfigurationChildInstances, config);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstance = null;
                r.lastNonConfigurationChildInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
//5、 最后还要调用MainActivity的onCreate函数,这里不是直接调用MainActivity的onCreate函数,而是通过Instrumentation类的callActivityOnCreate函数来间接调用,前面我们说过,mInstrumentation在这里的作用是监控Activity与系统的交互操作,相当于是系统运行日志
                mInstrumentation.callActivityOnCreate(activity, r.state);
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

到这里经过一系列的调用和跨进程通信终于启动了Activity

Android 应用程序启动过程分析

Android 应用进程启动流程
Android进程启动流程(App启动)
Activity启动过程全解析
Android Launcher 启动 Activity 的工作过程
Android Application启动流程分析
Android应用程序启动过程源代码分析
写给Android App开发人员看的Android底层知识(2)
从应用角度看Android源码 - 是谁调用的ActivityThread的main方法
ActivityThread

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值