[置顶] Activity启动过程(一)AMS

   在前面《Android启动过程》中提到了System进程启动ActivityManagerService服务,AMS是由Android提供的用于管理Activity(不仅仅指Activity,还包括其他三个组件)运行状态的系统进程,则是平时编写APK应用程序时使用得最频繁的一个系统服务。
    AMS是通过ActivityStack(和其它数据结构)来记录、管理系统中的Activity(和其它组件)状态,并提供查询功能的一个系统服务,负责启动和调度应用程序组件。
一、AMS功能概述
1、回到《Android启动过程》中提到的使用SystemServer中ServerThread来启动AMS服务:

/** @path: \frameworks\base\services\java\com\android\server\SystemServer.java */ 
class ServerThread extends Thread {
    @Override
    public void run() {
        ......   
        // Critical services...
        boolean onlyCore = false;
        try {
            // 创建Activity Manager实例
            context = ActivityManagerService.main(factoryTest);
             .....
            // 将AMS注册到ServiceManager中(前面分析提到这一步是在创建PMS实例之后才进行注册)
            ActivityManagerService.setSystemProcess();
        } catch (RuntimeException e) {
        }
    }
}

2、如前所述,其是通过调用ActivityManagerService#main函数来创建AMS实例及AMS线程:

/** @path \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java<span style="font-family: Arial, Helvetica, sans-serif;"> **/ </span>
public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  
    static ActivityManagerService mSelf;  
 
    public static final Context main(int factoryTest) {
        /** 创建一个AThread线程 ,这里用来创建AMS实例*/
        AThread thr = new AThread();
        thr.start();   // 启动AMS线程
 
        synchronized (thr) {
        /** 这里运来判断AMS是否启动成功,失败则一直等待 **/
            while (thr.mService == null) {
                try {
                  // 注意这里会wait,直至AThread中AMS创建完成,调用notiyAll方法才唤醒
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }
 
        // 将AThread中创建的AMS实例赋值给m,再赋值给AMS静态变量mSelf
        ActivityManagerService m = thr.mService;
        mSelf = m;
      
        /** AMS两个最重要核心——
         *  - ActivityStack:Activity的记录者与管理者,同时也为AMS管理系统运行情况提供了基础
         *  - ActivityTask**/
        ActivityThread at = ActivityThread.systemMain();
        mSystemThread = at;
        Context context = at.getSystemContext();
        context.setTheme(android.R.style.Theme_Holo);
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        /** 创建一个ActivityStack对象 **/
        m.mMainStack = new ActivityStack(m, context, true); 
      
        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);
      
        synchronized (thr) {
            thr.mReady = true;
            // 唤醒AMS线程
            thr.notifyAll();
        }
 
        /*** 开始运行  ***/
        m.startRunning(null, null, null, null);
      
        return context;
    }
  
    static class AThread extends Thread {
        ActivityManagerService mService;
        boolean mReady = false;
 
        public AThread() {
            super("ActivityManager");
        }
 
        public void run() {
        /** 创建消息Loopr循环 **/
            Looper.prepare();
 
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
 
            /** 在这里创建AMS实例,用以作为系统中的Activity管理服务 **/
            ActivityManagerService m = new ActivityManagerService();
 
            synchronized (this) {
                mService = m;
                // 这里唤醒前面等待的线程
                notifyAll();
            }
 
            synchronized (this) {
                while (!mReady) {
                    try {
                       // 创建完成后wait等待,直至System线程将其唤醒
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
            Looper.loop();
        }
    }
}


3、通过ActivityManagerService#setSystemProcess将AMS注册到ServiceManager中

/** @path \frameworks\base\services\java\com\android\server\am\ActivityManagerService.java **/
public static void setSystemProcess() {
    try {
        // mSelf是静态变量,即前面启动的AMS实例
        ActivityManagerService m = mSelf;
       
        /** 这里通过ServiceManager来注册各种服务,其中AMS服务的主体是第一个即"activity" **/
        ServiceManager.addService("activity", m, true);
        ServiceManager.addService("meminfo", new MemBinder(m));
        ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
        ServiceManager.addService("dbinfo", new DbBinder(m));
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(m));
        }
        ServiceManager.addService("permission", new PermissionController(m));
 
        ApplicationInfo info =
            mSelf.mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS);
        mSystemThread.installSystemApplicationInfo(info);
  
        synchronized (mSelf) {
            ProcessRecord app = mSelf.newProcessRecordLocked(
                    mSystemThread.getApplicationThread(), info,
                    info.processName, false);
            app.persistent = true;
            app.pid = MY_PID;
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            mSelf.mProcessNames.put(app.processName, app.uid, app);
            synchronized (mSelf.mPidsSelfLocked) {
                mSelf.mPidsSelfLocked.put(app.pid, app);
            }
            mSelf.updateLruProcessLocked(app, true);
        }
    } catch (PackageManager.NameNotFoundException e) {
    }
}

    下面来看AMS是如何对Activity的启动产生影响的。

二、根Activity组件启动过程
1、Activity分类
    Activity组件分为两种类型:一种是根Activity,一种是子Activity。
1)根Activity以快捷方式图标的形式显示在应用程序启动器上,它的启动过程代表了一个Android应用程序的启动过程。
     根Activity在manifest.xml文件中的声明:

<activity
    android:name="com.loadingUI.LoadingActivity"
    android:label="@string/Loadinging_activity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
   Launcher组件在启动时,会向PackageManagerService查询系统中所有“action”等于"action.MAIN"以及"category"等于"category.LAUNCHER"的Activity组件,为每一个Activity组件创建一个快捷图标。

    (这也是为什么要将Launcher Activity的intent filter设为上述模式的原因)。
    当想启动一个应用时,通过点击应用程序启动器Launcher界面上的图标来启动

2)子Activity由根Activity或者其他子Activity来启动,它们可能与启动它们的Activity运行在同一进程,也可能运行在不同的进程中。
     启动方式分有显式启动与隐式启动两种。按照软件工程的角度,隐式启动可以减少Android应用程序组件之间的依赖耦合度。
    
2、根Activity(记为MainActivity)的总启动过程总结如下:
1)Launch组件向AMS发送启动根Activity组件的请求;
2)AMS响应Launch请求,将根Activity组件的信息保存下来,并向Launch发送一个进入中止状态的进程间通信请求。
3)Launch进入中止状态后,向AMS发送消息;
4)AMS接收到消息后,会检查启动根Activity的应用程序进程是否已经存在;若不存在,则启动该应用程序进程。
5)根Activity应用程序进程启动完成后,该进程会向AMS发送一个启动完成的进程间通信请求。
6)AMS将其保存的根Activity组件的信息发送给创建的根Activity应用程序进程,使得其继续启动根Activity组件。

3、根Activity详细启动过程
    先来分析启动的前几步如下图:
[置顶] Activity启动过程(一)AMS_第1张图片

    启动根Activity一般是通过点击快捷图标,Launch组件启动Activity。先看其点击响应函数:
1)Launcher类:

public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, View.OnTouchListener
1.2)点击响应函数Launcher#onClick:
/** \packages\apps\Launcher2\src\com\android\launcher2*/
public void onClick(View v) {
    ...
    Object tag = v.getTag();
    if (tag instanceof ShortcutInfo) {
        // 这里组装启动intent的信息
        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()));
 
        /** 看到通过这个函数用来启动一个应用的根Activity*/
        boolean success = startActivitySafely(v, intent, tag);
 
        if (success && v instanceof BubbleTextView) {
            mWaitingForResume = (BubbleTextView) v;
            mWaitingForResume.setStayPressed(true);
        }
    } 
    .......
}
    可以看到Launcher通过函数startActivitySafely来启动应用程序的根Activity;


1.2)Launcher#startActivitySafely方法:

/** \packages\apps\Launcher2\src\com\android\launcher2*/
boolean startActivitySafely(View v, Intent intent, Object tag) {
    boolean success = false;
    try {
    /** 函数很简单,只是对startActivity进行了安全封装*/
        success = startActivity(v, intent, tag);
    } catch (ActivityNotFoundException e) {
    ...
    }
    return success;
}
    可以看到startActivitySafely仅仅是对startActivity方法做了一个try-catch安全封装,用以安全启动,最终目的仍是调用startActivity来启动根Activity。


1.3)Launcher#startActivity函数:

boolean startActivity(View v, Intent intent, Object tag) {
    /*** 设置启动标志***/
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
    try {
        // Only launch using the new animation if the shortcut has not opted out (this is a
        // private contract between launcher and may be ignored in the future).
        boolean useLaunchAnimation = (v != null) &&
                !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
        UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
        LauncherApps launcherApps = (LauncherApps)
                this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
        // 当添加新的启动动画时,使用此启动方式
        if (useLaunchAnimation) {
            ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                    v.getMeasuredWidth(), v.getMeasuredHeight());
            if (user == null || user.equals(android.os.Process.myUserHandle())) {
              /** 注意这里将会调用父类的startActivity*/
                startActivity(intent, opts.toBundle());
            } else {
                launcherApps.startMainActivity(intent.getComponent(), user,
                        intent.getSourceBounds(), opts.toBundle());
            }
        } else { // 默认的启动方式
            if (user == null || user.equals(android.os.Process.myUserHandle())) {
             
              /** 调用父类Activity的startActivity来启动 **/
                startActivity(intent);
            } else {
                launcherApps.startMainActivity(intent.getComponent(), user,
                        intent.getSourceBounds(), null);
            }
        }
        return true;
    } catch (SecurityException e) {
    ...
    }
    return false;
}

    上面代码重要完成两个工作:
1> 设置Activity的启动标志位Intent.FLAG_ACTIVITY_NEW_TASK如果设置了此标志,这个activity将成为一个新task的历史堆栈中的第一个activity。这个task定义了一个原子组activities,用户可以对其进行移除。各种tasks可以移到前面或者后面;在一个特定的task中,所有的activities总是保持相同的顺序。当使用这个标志时,如果一个包含此activity的task已经运行了,新的activity不会启动;同时,当前的task将简单的被提到窗口最前面。查看FLAG_ACTIVITY_MULTIPLE_TASK可以禁止这个行为

2>  调用startActivity方法来继续启动根Activity组件;可以看到Launcher类中并未实现两个/一个参数的startActivity的方法,可知其在父类Activity中,这里将会调用Activity.startActivity()函数;

4、Activity类
    熟悉的Activity类:

    public class Activity extends ContextThemeWrapper
    implements LayoutInflater.Factory2,
    Window.Callback, KeyEvent.Callback,
    OnCreateContextMenuListener, ComponentCallbacks2,
    Window.OnWindowDismissedCallback

1、前面调用到的Activity#startActivity方法:

/** \frameworks\base\core\java\android\app\Activity.java*/ 
@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);
    }
}
    最终将会调用startActivityForResult来执行函数,第二个参数设为-1表示不需要知道最终的执行结果。


2、来分析Activity#startActivityForResult方法:

public void startActivityForResult(Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
 
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    /** mParent在调用attach函数时传入*/
    if (mParent == null) {
    /** Instrumentation类用以监控应用程序与系统之间的交互,
     *  这里通过其execStartActivity来启动Activity组件**/
        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) {
            mStartedActivity = true;
        }
 
        /** 有关界面加载SurfaceFlinger*/
        final View decor = mWindow != null ? mWindow.peekDecorView() : null;
        if (decor != null) {
            decor.cancelPendingInputEvents();
        }
    } else {
       ...
    }
    if (options != null && !isTopOfTask()) {
        mActivityTransitionState.startExitOutTransition(this, options);
    }
}
注意execStartActivity中的传参param:

1)mToken:

private IBinder mToken;

    mToken是一个Binder代理对象,指向了ActivityManagerService中一个类型为ActivityRecord的Binder本地对象。每一个已经启动的Activity组件在AMS(ActivityManagerService)中都存在一个对应的ActivityRecord对象,用来维护对应的Activity组件的运行状态及信息。
在调用execStartActivity函数时,传入实参mToken,使得可以将其传递给AMS,以便AMS接下来可以获得Launcher组件的详细信息。

前面提到调用execStartActivity方法,该方法是Instrumentation类中的方法。

5、Instrumentation类

    Instrumentation是执行application instrumentation代码的基类。当应用程序运行的时候instrumentation处于开启,Instrumentation将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的交互。Instrumentation implementation通过的AndroidManifest.xml中的<instrumentation>标签进行描述。

    Instrumentation似乎有些类似与window中的“钩子(Hook)函数”,在系统与应用程序之间安装了个“窃听器”。

1、Instrumentation#execStartActivity函数:

先看调用传参:

Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
函数源码:

/** \frameworks\base\core\java\android\app\Instrumentation.java*/
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
   
    /** mActivityMonitors定义:List<ActivityMonitor> mActivityMonitors;
     *  ActivityMoniter:有关特定的Intent的监视。
     *  一个ActivityMoniter类的实例通过函数addMonitor
     *  (Instrumentation.ActivityMonitor)添加到当前
     *  instrumentation中,一旦添加后,每当启动一个新的Activity,
     *  ActivityMoniter就会检测,如果匹配,其hit count计数更新
     *  等其他操作。一个ActivityMonitor也可以用来寻找一个Activity,
     *  通过waitForActivity()方法,这个函数将返直到匹配的活动被创建。*/
    // 这里与主线无关,可以不用关心
    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 {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
       
        // 主要的执行函数在这里,调用了ActivityManagerNative中的startActivity
        int result = ActivityManagerNative.getDefault()
            .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) {
    }
    return null;
}
   上述代码中最重要的作用是调用了 ActivityManagerNative.getDefault().startActivity方法;getDefault用以获取AMS的一个代理对象ActivityManagerNative,接着再调用它的成员函数startActivity来通知AMS将有一个Activity组件启动。


6、ActivityManagerNative类:
看一下其继承关系:

   /** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/
    public abstract class ActivityManagerNative extends Binder implements IActivityManager

1、ActivityManagerNative#getDefault函数:

    /** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/
    static public IActivityManager getDefault() {
        // 单例类Singleton中的函数,get是Singleton类中的方法,见下面附I
        return gDefault.get();
    }
   
    // Singleton为单例模式的实现,是个抽象类,见附一
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            // 前面AMS分析中提到的AMS的主要服务"activity",通过SM获取
            IBinder b = ServiceManager.getService("activity");
            ...
            IActivityManager am = asInterface(b);
            ...
            return am;
        }
    };
   
    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);
    }
    可以看到当调用getDefault函数时,会返回gDefault.get(),返回一个IActivityManager类;

附I、Singleton类

    再看一下gDefault的定义,gDefault是个泛型类Singleton的对象实例,Singleton是个单例模式实现类,它是一个抽象类,它的定义如下:

    /**
     * Singleton helper class for lazily initialization.
     * Modeled after frameworks/base/include/utils/Singleton.h
     */
    public abstract class Singleton<T> {
        private T mInstance;
 
        protected abstract T create();
 
        public final T get() {
            synchronized (this) {
                if (mInstance == null) {
                    mInstance = create();
                }
                return mInstance;
            }
        }
    }
    可以看到gDefault的定义是Singleton<IActivityManager>,调用get函数则是返回IActivityManager的具体实例对象。


    在定义gDefault时,需要重写abstract函数create();在create函数中,可以看到它通过ServiceManager获取到一个服务名为"activity"的服务代理对象即一个引用了ActivtyManagerService的代理对象。
    而后通过asInterface将其封装成一个ActivityManagerProxy代理对象
    因此调用getDefault最终获取到的返回结果时ActivityManagerService的代理对象。   
回到前面的步骤可知,ActivityManagerNative.getDefault().startActivity方法最终调用的是ActivityManagerProxy.startActivity方法。

2)ActivityManagerProxy类:(ActivityManagerNative的内部类)

/** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/
class ActivityManagerProxy implements IActivityManager {
   
    public ActivityManagerProxy(IBinder remote) {
        mRemote = remote;
    }
 
    public IBinder asBinder() {
        return mRemote;
    }
 
    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 {
        /*** 写入启动Activity的信息到Parcel对象data中 **/
        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);
        }
        /** 通过Binder进行进程间通信,通过mRemote来向AMS发送START_ACTIVITY_TRANSACTION类型
         *  的进程间请求 **/
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }
}
    和通常的Binder通信机制相同,这里使用ActivityManagerProxy将Activity组件的信息封装到一个Parcel对象中,通过Binder机制传递给AMS,发起进程间通信请求。接下来的启动操作则会在AMS中进行。

你可能感兴趣的:([置顶] Activity启动过程(一)AMS)