Android之Activity启动源码分析 Launcher启动Activity 应用内启动Activity

版权声明:本文为博主原创文章,转载请标明出处 https://blog.csdn.net/qq_30993595/article/details/81773286

在平时的使用中,我们启动一个Activity用的最多的方式有两种,一种是在手机桌面点击应用icon启动应用,即启动应用的第一个Activity,也就是在Launcher启动Activity;另一种是在应用内部通过startActivity方法启动Activity,今天就对这两种方式进行分析,多进行FrameWork层的分析非常有利于我们平时在应用层开发处理一些棘手的问题

以下代码分析基于API24

在Launcher启动Activity

在讲这种启动方式的时候,先思考下Launcher是个啥东西?

假设你有这样一个APP,它有一个名为LauncherActivity的Activity,它的内容主要就是检索手机安装了哪些应用,然后显示对应的APPicon,最后对icon做监听,只要点击icon,就启动相应的APP,长按icon就可以提升卸载APP。

那这种APP理论上是不是可以做?如果你做了,那这个APP是不是跟手机桌面是一样的?

不用怀疑,手机桌面本质上就是一个这样的应用,呈现给我们看的是一个名称为LauncherActivity的Activity,看看它的源码

/**
 * 显示一个可以通过给定的Intent启动的Activity列表,通过点击icon启动
 *  */
public abstract class LauncherActivity extends ListActivity {
    Intent mIntent;
    PackageManager mPackageManager;
    IconResizer mIconResizer;

    /**
     * item实体类
     */
    public static class ListItem {
        public ResolveInfo resolveInfo;//解析icon的类
        public CharSequence label;//标题
        public Drawable icon;//应用logo图标
        public String packageName;//应用包名
        public String className;//要启动的类名,一般是activity名称
        public Bundle extras;//传递的数据

        ListItem(PackageManager pm, ResolveInfo resolveInfo, IconResizer resizer) {
            this.resolveInfo = resolveInfo;
            label = resolveInfo.loadLabel(pm);
            ComponentInfo ci = resolveInfo.activityInfo;
            if (ci == null) ci = resolveInfo.serviceInfo;
            if (label == null && ci != null) {
                label = resolveInfo.activityInfo.name;
            }

            if (resizer != null) {
                icon = resizer.createIconThumbnail(resolveInfo.loadIcon(pm));
            }
            packageName = ci.applicationInfo.packageName;
            className = ci.name;
        }

        public ListItem() {
        }
    }

    /**
     * ListView的adapter
     */
    private class ActivityAdapter extends BaseAdapter implements Filterable {
        private final Object lock = new Object();
        private ArrayList<ListItem> mOriginalValues;

        protected final IconResizer mIconResizer;
        protected final LayoutInflater mInflater;

        protected List<ListItem> mActivitiesList;

        private Filter mFilter;
        private final boolean mShowIcons;

        public ActivityAdapter(IconResizer resizer) {
            mIconResizer = resizer;
            mInflater = (LayoutInflater) LauncherActivity.this.getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            mShowIcons = onEvaluateShowIcons();
            mActivitiesList = makeListItems();
        }

        public Intent intentForPosition(int position) {
            if (mActivitiesList == null) {
                return null;
            }

            Intent intent = new Intent(mIntent);
            ListItem item = mActivitiesList.get(position);
            intent.setClassName(item.packageName, item.className);
            if (item.extras != null) {
                intent.putExtras(item.extras);
            }
            return intent;
        }
        //点击icon调用的方法
        public ListItem itemForPosition(int position) {
            if (mActivitiesList == null) {
                return null;
            }
            return mActivitiesList.get(position);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view;
            if (convertView == null) {
                view = mInflater.inflate(
                        com.android.internal.R.layout.activity_list_item_2, parent, false);
            } else {
                view = convertView;
            }
            bindView(view, mActivitiesList.get(position));
            return view;
        }

        private void bindView(View view, ListItem item) {
            TextView text = (TextView) view;
            text.setText(item.label);
            if (mShowIcons) {
                if (item.icon == null) {
                    item.icon = mIconResizer.createIconThumbnail(item.resolveInfo.loadIcon(getPackageManager()));
                }
                text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
            }
        }
    }

    /**
     * 用于调整图标大小以匹配默认图标大小的实用程序类。 
     */
    public class IconResizer {
        // Code is borrowed from com.android.launcher.Utilities. 
        private int mIconWidth = -1;
        private int mIconHeight = -1;

        private final Rect mOldBounds = new Rect();
        private Canvas mCanvas = new Canvas();

        public IconResizer() {
            mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
                    Paint.FILTER_BITMAP_FLAG));

            final Resources resources = LauncherActivity.this.getResources();
            mIconWidth = mIconHeight = (int) resources.getDimension(
                    android.R.dimen.app_icon_size);
        }

        /**
         * 获取icon缩略图,不是线程安全的,必须在UI线程调用,我们如果需要获取缩略图的功能也可以用这个方法
         */
        public Drawable createIconThumbnail(Drawable icon) {
            int width = mIconWidth;
            int height = mIconHeight;

            final int iconWidth = icon.getIntrinsicWidth();
            final int iconHeight = icon.getIntrinsicHeight();

            if (icon instanceof PaintDrawable) {
                PaintDrawable painter = (PaintDrawable) icon;
                painter.setIntrinsicWidth(width);
                painter.setIntrinsicHeight(height);
            }

            if (width > 0 && height > 0) {
                if (width < iconWidth || height < iconHeight) {
                    final float ratio = (float) iconWidth / iconHeight;

                    if (iconWidth > iconHeight) {
                        height = (int) (width / ratio);
                    } else if (iconHeight > iconWidth) {
                        width = (int) (height * ratio);
                    }

                    final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
                                Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
                    final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
                    final Canvas canvas = mCanvas;
                    canvas.setBitmap(thumb);
                    // Copy the old bounds to restore them later
                    // If we were to do oldBounds = icon.getBounds(),
                    // the call to setBounds() that follows would
                    // change the same instance and we would lose the
                    // old bounds
                    mOldBounds.set(icon.getBounds());
                    final int x = (mIconWidth - width) / 2;
                    final int y = (mIconHeight - height) / 2;
                    icon.setBounds(x, y, x + width, y + height);
                    icon.draw(canvas);
                    icon.setBounds(mOldBounds);
                    icon = new BitmapDrawable(getResources(), thumb);
                    canvas.setBitmap(null);
                } else if (iconWidth < width && iconHeight < height) {
                    final Bitmap.Config c = Bitmap.Config.ARGB_8888;
                    final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
                    final Canvas canvas = mCanvas;
                    canvas.setBitmap(thumb);
                    mOldBounds.set(icon.getBounds());
                    final int x = (width - iconWidth) / 2;
                    final int y = (height - iconHeight) / 2;
                    icon.setBounds(x, y, x + iconWidth, y + iconHeight);
                    icon.draw(canvas);
                    icon.setBounds(mOldBounds);
                    icon = new BitmapDrawable(getResources(), thumb);
                    canvas.setBitmap(null);
                }
            }

            return icon;
        }
    }

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        mPackageManager = getPackageManager();

        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
            requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
            setProgressBarIndeterminateVisibility(true);
        }
        onSetContentView();

        mIconResizer = new IconResizer();

        mIntent = new Intent(getTargetIntent());
        mIntent.setComponent(null);
        mAdapter = new ActivityAdapter(mIconResizer);

        setListAdapter(mAdapter);
        getListView().setTextFilterEnabled(true);

        updateAlertTitle();
        updateButtonText();

        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
            setProgressBarIndeterminateVisibility(false);
        }
    }
    /**
     * 设置LauncherActivity的layout
     */
    protected void onSetContentView() {
        setContentView(com.android.internal.R.layout.activity_list);
    }

    /**
    *点击item启动应用的activity
    */
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = intentForPosition(position);
        startActivity(intent);
    }

    /**
     * 调用上方adapter的方法
     */
    protected Intent intentForPosition(int position) {
        ActivityAdapter adapter = (ActivityAdapter) mAdapter;
        return adapter.intentForPosition(position);
    }

    /**
     * 查询有多少应用
     */
    protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) {
        return mPackageManager.queryIntentActivities(queryIntent, /* no flags */ 0);
    }


    /**
     * 查询有多少应用
     */
    public List<ListItem> makeListItems() {
        // Load all matching activities and sort correctly
        List<ResolveInfo> list = onQueryPackageManager(mIntent);
        onSortResultList(list);

        ArrayList<ListItem> result = new ArrayList<ListItem>(list.size());
        int listSize = list.size();
        for (int i = 0; i < listSize; i++) {
            ResolveInfo resolveInfo = list.get(i);
            result.add(new ListItem(mPackageManager, resolveInfo, null));
        }

        return result;
    }
}

我这里没有贴完整代码,只保留了一些主要的,可以看到代码并不复杂,总共四五百行代码,主要逻辑就是

  • 先通过PackageManager类的queryIntentActivities方法,获取所有需要展示的应用集合
  • 将应用集合设置到adapter,然后绑定listview显示
  • 每个item实体为ListItem对象,封装了要启动的应用的信息
  • 重写onListItemClick方法,响应点击事件,启动相应的应用,说是启动应用,其实是启动这个应用在mainfest.xml中注册了android.intent.action.MAIN这个action的Activity

继续看看onListItemClick方法

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = intentForPosition(position);
        startActivity(intent);
    }
    protected Intent intentForPosition(int position) {
        ActivityAdapter adapter = (ActivityAdapter) mAdapter;
        return adapter.intentForPosition(position);
    }
    public Intent intentForPosition(int position) {
            if (mActivitiesList == null) {
                return null;
            }

            Intent intent = new Intent(mIntent);
            ListItem item = mActivitiesList.get(position);
            intent.setClassName(item.packageName, item.className);
            if (item.extras != null) {
                intent.putExtras(item.extras);
            }
            return intent;
        }

看到它的启动方法其实跟我们平时在应用里启动Activity是差不多的,都是构建一个Intent,然后通过Activity类的startActivity方法去启动Activity,继续看这个方法的调用

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

在应用内启动Activity

我们在App内启动同一个APP的Activity或者其它应用的Activity,方法都是类似的,构建一个Intent,然后调用startActivity

//启动本应用activity
Intent intent = new Intent(this,WebViewAct.class);
startActivity(intent);
//启动第三方应用
Intent intent = new Intent();
//intent.setAction(mAction);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(new ComponentName(mPackageName,mClassName));
startActivity(intent);

这两种方法最终也还是会调用到Activity类的startActivity方法

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

汇合

综上所述,不管是在桌面启动Activity还是在应用中启动Activity,最终都会走到同一处,也就是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 {
            startActivityForResult(intent, -1);
        }
    }

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

经过层层调用,最后走到startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) 这个方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == 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) {
                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);
            }
        }
    }

mParent

这里首先会判断mParent ,那这个mParent 是什么呢,其实也是一个Activity,但是从这个命名我们知道它表达的是当前Activity的父Activity

一个Activity的父Activity,好像平时我们开发中没用过Activity嵌套子Activity开发吧,一般都是Activity嵌套Fragment来使用;没错,在很早以前的版本要实现一个Activity包含多个页面使用的是TabActivity,这样就会出现TabActivity嵌套子Activity,然后在子Activity启动时候,将TabActivity对象赋值给了ActivityClientRecord的parent对象,当执行到attach方法的时候,将这个parent对象再赋值给mParent

不过现在没有这种使用了,基本上可以不用考虑这个了,所以这个方法里就直接进入mParent == null的条件里

Instrumentation

Instrumentation翻译过来是仪表,仪器的意思,在应用中可以理解为应用进程的管家,一个工具类的性质,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。ActivityThread要创建或暂停某个Activity时(activity的生命周期方法),都需要通过Instrumentation来进行具体的操作。

稍微接触过Activity启动的同学应该都了解过ActivityManagerService,ActivityThread这两个东西,它们也是负责Activity的相关活动的,现在又来个Instrumentation,也是负责Activity相关活动的,那它们几个什么关系呢?

可以把ActivityManagerService比喻成集团CEO,负责创立、指挥、调度各个子公司运行,每个子公司比喻成一个Activity
ActivityThread是子公司老板,虽然负责Activity的相关活动,但前提是要遵循ActivityManagerService的指挥
Instrumentation就可以看成是子公司老板助理了,负责公司具体的大事小情,不过听从ActivityThread吩咐

mMainThread.getApplicationThread

mMainThread是ActivityThread,通过getApplicationThread获取到的ApplicationThread,是ActivityThread的内部类

execStartActivity

接下来就会执行到Instrumentation.execStartActivity方法了

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);
                    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 = 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) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

介绍下参数

  • Context who:当前Activity的上下文(context)
  • IBinder contextThread:从调用方法可以看出它是ActivityThread的内部类ApplicationThread,继承ApplicationThreadNative;同时可以看到这是一个IBinder对象,说明它的作用就是用于进程间通讯的Binder对象
  • IBinder token:Activity的创建与关联时候(下面的内容会提到)传入的Activity信息,代表当前Activity,后续AMS可以通过它和contextThread知道是谁请求自己的
  • Activity target:当前Activity对象
  • Intent intent:构建的Intent,携带着目的Activity的信息
  • int requestCode:请求码
  • Bundle options:如何启动Activity的配置,比如加入转场动画

我们知道,每个应用程序都有一个主线程/UI线程,也就是ActivityThread,一个应用程序就是由ActivityThread这样一个主线程和若干个子线程组成的(像平时说的Application代表一个应用,其实它是ActivityThread的上下文;例如Context是Activity的上下文);ActivityThread管理着所有的Activity操作;但是又是谁去通知它做这些事呢?

没错,就是ActivityManagerService(以下简称AMS)了,AMS是服务端,整个手机上的应用中的Activity操作全部由它来进行调度,AMS与每个应用的ActivityThread处于不同的进程,它去通知ActivityThread就涉及到Binder通信了(Android中IPC)

ActivityManagerNative(以下简称AMN)

继续看上面的方法,启动Activity真正的实现是由ActivityManagerNative.getDefault()的startActivity方法来完成

    /**
     * 获取系统中全局的ActivityManager,这是与远程AMS通信的接口
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    //这个方法用于将AMS的IBinder对象转换成客户端所需的AIDL接口类型的对象
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            //如果是同一个进程,那就直接返回ActivityManagerNative自己
            return in;
        }
        //如果跨进程,那就将这个IBinder构建成代理对象返回
        return new ActivityManagerProxy(obj);
    }

Singleton 是一个单例的封装类,第一次调用get方法会通过create()方法初始化一个IActivityManager 对象,IActivityManager继承IInterface接口

从create()方法可以看出先通过服务名向Service Manager(以下简称SM,此处的Service Manager是指Native层的ServiceManager(C++),并非指framework层的ServiceManager(Java)。)查询AMS这个服务(至于SM是什么,可以查看博主之前的Binder通信系列文章),然后SM返回AMS的IBinder,接着通过asInterface返回一个AMS的Binder代理对象,具体实现是ActivityManagerProxy(以下简称AMP)

注意:

这里说的SM是对用户透明的,让你感觉是直接跟它通信;其实不然,在Binder机制中这里的过程主要分为以下几步:

  • 首先肯定是系统启动后,AMS通过Binder驱动在SM中注册,将自己的名字和Binder本地对象保存在SM的查询表中
  • Client要想申请调用某个服务(比如这里获取AMS服务一方作为Client,AMS作为Server),需要告诉Binder驱动,并携带Server的信息,比如AMS在SM中注册的名称
  • Binder驱动将Client的请求发送给SM
  • SM有一个Loop,不停获取消息,这里将Binder驱动发送过来的消息进行处理,通过名称在表里查询,将获取到的AMS的Binder本地对象返回给Binder驱动
  • Binder驱动将获取到的AMS的Binder本地对象转换成Binder代理对象发送给Client
  • Client获取到AMS的Binder代理对象再通过Binder驱动向AMS发起通讯
  • Binder驱动进行内存映射,将AMS的用户空间和内核空间都映射到一块物理内存
  • 这样Client与Server的信息交换实际上都在这块物理内存,就仿佛是在直接通信
讲到这里就涉及到了好几个类,我们总结下:
  • 首先用户启动Activity,经过调用后由Instrumentation这个工具类去处理,但是因为所有的Activity的操作都需要经过AMS的调度,所以Instrumentation所在的应用进程与AMS便存在一个跨进程的通信的问题
  • 跨进程通信基于Binder机制,在应用层使用Binder就要利用AIDL去实现
  • 使用AIDL就需要编写一个继承IInterface接口的接口,这个接口定义了一系列的Activity的操作方法,它是应用与AMS通信的桥梁,定义了双方都遵循的规则,在这里是IActivityManager接口
  • 既然定义了接口,那Server端和Clent端就得实现这些接口方法,以供启动方调用并将消息发送给AMS去真正实现操作
  • 这里由AMN实现了该接口,并且它还继承Binder,这也间接实现了IBinder接口,说明这个AMN具备跨进程传输能力,同时由内部类AMP重写这些方法供启动方(Client端)调用,并且将数据进行序列化发送给AMS(Server端),AMS也间接实现了接口中的方法,是这些方法真正的功能实现
  • AIDL通信规则建立后,通过AMN类内部gDefault 这个成员可以知道,先获取AMS的IBinder,然后判断如果启动Activity一方和AMS处于同一进程,那直接返回即AMN;如果不在同一进程,那就返回Binder的代理对象即AMP;然后就可以与AMS通信了

其实这些IActivityManager,AMS,AMP,AMN就是AIDL的实现,就是为了跨进程通信,具体AIDL实现细节可参考Android通过AIDL达到进程间通信,再结合Binder机制的理解Android中进程间通信Binder机制,重点看AIDL接口对应的Java文件,相信你看完后会更容易理解本篇文章中的实现细节

IActivityManager是一个IInterface,它代表远程Service具有什么能力(类似AIDL工具生成的接口),AMN指的是Binder本地对象(类似AIDL工具生成的Stub类),这个类是抽象类,它的实现是AMS(类似于AIDL中服务端Service类里面的内部类Stub,实现具体功能);因此对于Activity的最终操作都会进入AMS真正实现;同时AMN里面有一个非公开类AMP, 它代表的就是Binder代理对象(类似于AIDL工具生成的Proxy类);你如果写过AIDL就会发现这跟一个标准的AIDL模型是一样的

了解这些调用细节后,我们继续看,Instrumentation最终会调用到AMN内部类AMP的startActivity方法

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池中获取Parcel对象(通讯载体),装载传递给AMS的数据
        Parcel data = Parcel.obtain();
        //同上,不过是装载AMS返回的数据
        Parcel reply = Parcel.obtain();
        //Binder唯一标志
        data.writeInterfaceToken(IActivityManager.descriptor);
        //caller是ActivityThread的内部类ApplicationThread
        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);
        }
        //发送类型为START_ACTIVITY_TRANSACTION的请求给AMS
        //transact方法运行在客户端,通过该方法发起远程过程调用(RPC)请求,同时当前线程挂起;
        //然后服务端的onTransact方法会被调用,直到RPC过程返回
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        //当前线程继续执行,并从_reply中取出RPC过程的返回结果,也就是返回_reply中的数据
        //这里可能会读出异常,比如没在xml中注册Activity
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
}

由上面提到的Android通过AIDL达到进程间通信那篇文章可以知道,AMP中的mRemote是一个IBinder,并且是BinderProxy类型,也就是Binder代理,所以这里通过Binder代理对象(mRemote)将客户端的请求进行封装后调用transact方法;

/**
     *
     * @param code Binder只能传递数据,每个AIDL函数都有一个编号,在跨进程的时候传递编号告诉Server调用哪个函数
     * @param data Client要发送的数据
     * @param reply Server返回的数据
     * @param flags
     * @return
     * @throws RemoteException
     */
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);
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;

可以看到,BinderProxy调用了transactNative这个native方法,这个方法定义在frameworks/base/core/jni/android_util_Binder.cpp文件里,经过jni调用android_os_BinderProxy_transact函数

static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */

    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},

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

    //将java中的Parcel转化成c++中的Parcel
    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

    //这里的target是BpBinder对象
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    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) {
        time_binder_calls = should_time_binder_calls();
        if (time_binder_calls) {
            start_millis = uptimeMillis();
        }
    }

    //调用BpBinder的transact
    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;
    }

    //根据transact执行情况抛出相应异常
    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
    return JNI_FALSE;
}
//gBinderProxyOffsets.mNativeData中保存的是BpBinder对象
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
    return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
}

接下来经过一系列函数调用,最终调用到了talkWithDriver()跟驱动交互,这个函数最后通过ioctl系统调用,Client进程陷入内核态,Client调用startActivity方法的线程挂起等待返回;驱动完成一系列的操作之后唤醒AMS进程,调用了AMS进程本地对象的onTransact函数(实际上由Server端线程池完成),这里就调用了AMN的onTransact方法(AMN即Binder本地对象):

@Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
            case START_ACTIVITY_TRANSACTION:
            {
                data.enforceInterface(IActivityManager.descriptor);
                IBinder b = data.readStrongBinder();
                IApplicationThread app = ApplicationThreadNative.asInterface(b);
                String callingPackage = data.readString();
                Intent intent = Intent.CREATOR.createFromParcel(data);
                String resolvedType = data.readString();
                IBinder resultTo = data.readStrongBinder();
                String resultWho = data.readString();
                int requestCode = data.readInt();
                int startFlags = data.readInt();
                ProfilerInfo profilerInfo = data.readInt() != 0
                        ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
                Bundle options = data.readInt() != 0
                        ? Bundle.CREATOR.createFromParcel(data) : null;
                int result = startActivity(app, callingPackage, intent, resolvedType,
                        resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
                reply.writeNoException();
                reply.writeInt(result);
                return true;
            }
        }

        return super.onTransact(code, data, reply, flags);
    }

在AMS进程里面,onTransact根据编号调用相关函数;在这个例子里面,调用了自己的startActivity方法,但AMN的具体实现是AMS,从这里开始就正式进入AMS了:

@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

这里又转到了startActivityAsUser

@Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        //检查调用者是否有相应的权限
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }

这个mActivityStarter是ActivityStarter,是一个Activity启动管理类,将Intent和flag转化成一个Activity及相关联的task和stack;以前老版本是直接用ActivityStackSupervisor处理

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {

                .......

        //根据给定的Intent,判断是否是显示启动
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

        .......

        //根据Intent匹配相应的Activity , 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

                .......

        final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);
        return res;

}

接下来继续调用

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;

        .......

        //创建ActivityRecord对象
        //每次启动一个Actvity会有一个对应的ActivityRecord对象,代表Activity在堆栈的一个记录
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
                options, sourceRecord);

            .......

        err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true, options, inTask);

        //将Activity对应的TASK移动到前台            
        postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);

        return err;
}

在这个方法里还会做一些校验,比如调用进程是否还存在;还会处理一个Intent.FLAG_ACTIVITY_FORWARD_RESULT这种flag的情况,因为会有这种需求,就是从ActivityA跳转到ActivityB,ActivityB再跳转到ActivityC,但是按返回键需要返回到ActivityA,在这时候就需要将调用者从ActivityB改成ActivityA;接着还会判断是否匹配到Intent的目标,以及校验调用者是否有权限启动目标Activity,然后将这些结果封装到ActivityRecord中,接着执行startActivityUnchecked方法

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

        .......
        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);

        .......
        if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
        }
        return START_SUCCESS;
}

这个方法处理逻辑很复杂,比如我们平时启动activity的flag,比如FLAG_ACTIVITY_NEW_TASK,这里都会做处理;还有Activity的启动模式,taskAffinity属性,是否需要为这个Activity新建一个task等都会在这里处理

mTargetStack是ActivityStack,我们知道一个ActivityRecord代表一个Activity,一个Activity可能有多个ActivityRecord,因为一个Activity可以实例化多个,取决于启动模式;
一系列相关的ActivityRecord组成了TaskRecord;一系列的TaskRecord又组成了ActivityStack;接下来看看方法

final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
            ActivityOptions options) {
        TaskRecord rTask = r.task;

        TaskRecord task = null;
        if (!newTask) {
            // 如果目标Activity不用新开task,那就从已存在的task中找出
            boolean startIt = true;
            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
                task = mTaskHistory.get(taskNdx);
                if (task.getTopActivity() == null) {
                    // All activities in task are finishing.
                    continue;
                }
                if (task == r.task) {
                    // 在这里进行添加
                    if (!startIt) {

                        task.addActivityToTop(r);
                        r.putInHistory();
                        addConfigOverride(r, task);
                        if (VALIDATE_TOKENS) {
                            validateAppTokensLocked();
                        }
                        ActivityOptions.abort(options);
                        return;
                    }
                    break;
                } else if (task.numFullscreen > 0) {
                    startIt = false;
                }
            }
        }

        // 将Activity推到栈顶
        if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
            //如果没有将Activity推到栈顶,那么就不把onUserLeaving回调给当前Activity
            mStackSupervisor.mUserLeaving = false;
            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
                    "startActivity() behind front, mUserLeaving=false");
        }

        task = r.task;

        // 将Activity添加到历史栈中
        task.addActivityToTop(r);
        task.setFrontOfTask();

        .......
        //在在WindowManagerService中注册,这样才能显示出来
        addConfigOverride(r, task);

        .......
}

void addConfigOverride(ActivityRecord r, TaskRecord task) {
        final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
        // TODO: VI deal with activity
        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
                task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig,
                task.mResizeMode, r.isAlwaysFocusable(), task.isHomeTask(),
                r.appInfo.targetSdkVersion);
        r.taskConfigOverride = task.mOverrideConfig;
    }

这个方法主要是将Activity推到栈顶并且通知WindowManagerService,这样startActivity的一系列准备工作基本上完成了;这时候再回到上一个方法,即ActivityStarter的startActivityUnchecked方法,继续调用ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked方法

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        //待启动Activity对应的Task为前台Task时,调用该Task对应ActivityStack的resumeTopActivityUncheckedLocked函数
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        //否则只是调用当前前台栈的resumeTopActivityUncheckedLocked
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
}

接下来调用到ActivityStack的resumeTopActivityUncheckedLocked方法

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            //防止递归启动 保证每次只有一个Activity执行resumeTopActivityLocked()操作.
            return false;
        }

        boolean result = false;
        try {
            // 修改标志位 防止递归
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
}

然后开始启动操作,进入resumeTopActivityInnerLocked方法

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");

        if (!mService.mBooting && !mService.mBooted) {
            // 系统还没准备好,不允许启动activity
            return false;
        }

        ActivityRecord parent = mActivityContainer.mParentActivity;
        if ((parent != null && parent.state != ActivityState.RESUMED) ||
                !mActivityContainer.isAttachedLocked()) {
            // 如果一个activity的父activity没有resumed,就不启动该子activity
            return false;
        }

                final TaskRecord prevTask = prev != null ? prev.task : null;
            if (next == null) {
            //找不到要启动的activity,就回到桌面activity
            return isOnHomeDisplay() &&
                mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
            }

        // 如果要启动的activity就在栈顶,那就不做处理
        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                    mStackSupervisor.allResumedActivitiesComplete()) {
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            return false;
        }

        .......

        // 处于睡眠关机,栈顶activity已经暂停的情况下
        if (mService.isSleepingOrShuttingDownLocked()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            return false;
        }

                .......


        // 如果当前正在暂停这个activity,直接返回
        if (!mStackSupervisor.allPausedActivitiesComplete()) {
            return false;
        }

        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

        // 需要暂停当前activity,然后resume要启动的activity
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        //暂停其它所有堆栈中的或者返回栈中的activity
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
        if (mResumedActivity != null) {
            //暂停当前处于resume的mResumedActivity ,它也可能是Launchactivity
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }

        if (pausing) {
            // 如果待启动的activity已经启动过,就将这个activity所处的进程置于LRU列表的顶部,以免被杀重新启动浪费资源
            if (next.app != null && next.app.thread != null) {
                mService.updateLruProcessLocked(next.app, true, null);
            }
            return true;
        } 

        .......

        // 确保该Activity所在的应用程序不在停止
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.userId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + next.packageName + ": " + e);
        }

        // 正在启动下一个Activity,需要告诉windowManager,前一个activity会被很快隐藏,这样在计算屏幕方向时,windowmanager就会忽略它
        boolean anim = true;
        if (prev != null) {
            if (prev.finishing) {
                if (mNoAnimActivities.contains(prev)) {
                    anim = false;
                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    mWindowManager.prepareAppTransition(prev.task == next.task
                            ? TRANSIT_ACTIVITY_CLOSE
                            : TRANSIT_TASK_CLOSE, false);
                }
                mWindowManager.setAppVisibility(prev.appToken, false);
            } else {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare open transition: prev=" + prev);
                if (mNoAnimActivities.contains(next)) {
                    anim = false;
                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    mWindowManager.prepareAppTransition(prev.task == next.task
                            ? TRANSIT_ACTIVITY_OPEN
                            : next.mLaunchTaskBehind
                                    ? TRANSIT_TASK_OPEN_BEHIND
                                    : TRANSIT_TASK_OPEN, false);
                }
            }
        } else {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
            if (mNoAnimActivities.contains(next)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
            }
        }

        Bundle resumeAnimOptions = null;
        if (anim) {
            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
            if (opts != null) {
                resumeAnimOptions = opts.toBundle();
            }
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }

        ActivityStack lastStack = mStackSupervisor.getLastStack();
        //如果要启动的activity所在进程已经存在,且activity已经启动过了
        if (next.app != null && next.app.thread != null) {

            // 如果上一个activity是半透明的,则强制对下一个activity进行可见性更新
            //以便将其添加到WM的打开应用列表
            final boolean lastActivityTranslucent = lastStack != null
                    && (!lastStack.mFullscreen
                    || (lastStack.mLastPausedActivity != null
                    && !lastStack.mLastPausedActivity.fullscreen));

            // 正在设置Activity为可见.
            if (!next.visible || next.stopped || lastActivityTranslucent) {
                mWindowManager.setAppVisibility(next.appToken, true);
            }

            // schedule launch ticks to collect information about slow apps.
            next.startLaunchTickingLocked();

            ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
            ActivityState lastState = next.state;

            mService.updateCpuStats();

            //设置待启动Activity状态为resume
            next.state = ActivityState.RESUMED;
            //设置当前activity为当前活动activity
            mResumedActivity = next;
            next.task.touchActiveTime();
            mRecentTasks.addLocked(next.task);
            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            mService.updateOomAdjLocked();

            // 让WM基于新的activity顺序重新评估屏幕方向
            boolean notUpdated = true;
            if (mStackSupervisor.isFocusedStack(this)) {
                Configuration config = mWindowManager.updateOrientationFromAppTokens(
                        mService.mConfiguration,
                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
                if (config != null) {
                    next.frozenBeforeDestroy = true;
                }
                notUpdated = !mService.updateConfigurationLocked(config, next, false);
            }

            ......

            try {
                // 分发所有pending结果
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {、
                        next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }

                if (next.newIntents != null) {
                        //如果Intent不为空,回调NewIntent方法传入Intent
                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
                }

                // 应用程序不再会被stop
                mWindowManager.notifyAppStopped(next.appToken, false);

                //回调onResume
                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);

                mStackSupervisor.checkReadyForSleepLocked();

            } catch (Exception e) {
                // Whoops, need to restart this activity!
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                        + lastState + ": " + next);
                next.state = lastState;
                if (lastStack != null) {
                    lastStack.mResumedActivity = lastResumedActivity;
                }
                Slog.i(TAG, "Restarting because process died: " + next);
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
                        mStackSupervisor.isFrontStack(lastStack)) {
                    next.showStartingWindow(null, true);
                }
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }

            // From this point on, if something goes wrong there is no way
            // to recover the activity.
            try {
                completeResumeLocked(next);
            } catch (Exception e) {
                // If any exception gets thrown, toss away this
                // activity and try the next one.
                Slog.w(TAG, "Exception thrown during resume of " + next, e);
                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                        "resume-exception", true);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        } else {
            // 到这里就需要重新启动activity,或者创建进程启动activity
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null, true);
                }
            }
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        return true;
}

这个方法也是比较复杂的,主要会有以下判断处理

  • 系统没有准备好,不予启动
  • 待启动activity的父activity没有启动,不予启动
  • 找不到要启动的activity,不予启动
  • 当mResumedActivity不为null,即当前activity不为空,就pause当前activity
  • 如果待启动的activity所在应用程序存在且activity已经启动过了,就resume这个activity
  • 否则就重新启动这个activity或者创建应用进程再启动这个activity

需要重新启动或者创建进程的话就进入ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 判断Activity所在的应用程序是否还在
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {

                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                //这里表明待启动activity的应用已经启动了,那么就启动activity
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

        }
        //否则就通过zygote进程fork应用进程,然后启动activity
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
}

这个方法中就有一个很重要的操作:如果要启动的Activity所在的应用进程不存在,比如从桌面冷启动一个应用,这就需要新创建一个新的进程了

其实Android中的四大组件的使用startactivity,startService,sendBrocast,ContentResolver.query,如果判断这些组件所在进程不存在,最终都会走到AMS的startProcessLocked方法,这个方法主要一点就是通知Zygote进程(AMS处于system-server进程,这就涉及到system-server进程和Zygote进程之间的通信,Android在这里使用的是Socket作为IPC方式)去fork一个APP进程

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        long startTime = SystemClock.elapsedRealtime();
        ProcessRecord app;
        //不处于孤立进程
        if (!isolated) {
            //根据进程名和进程uid获取进程对应的ProcessRecord
            //ProcessRecord封装了正在运行的进程的完整信息
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            checkTime(startTime, "startProcess: after getProcessRecord");

            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                // 如果当前进程处于后台进程,就判断是否在Bad进程列表
                if (mAppErrors.isBadProcessLocked(info)) {
                    return null;
                }
            } else {
                // 如果用户明确启动该进程,则清除其crash计数,保证其不处于Bad进程列表,直到下次再弹出crash框
                mAppErrors.resetProcessCrashTimeLocked(info);
                if (mAppErrors.isBadProcessLocked(info)) {
                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                            UserHandle.getUserId(info.uid), info.uid,
                            info.processName);
                    mAppErrors.clearBadProcessLocked(info);
                    if (app != null) {
                        app.bad = false;
                    }
                }
            }
        } else {
            // 如果是孤立进程,就没办法重用已存在的进程
            app = null;
        }

        ......

        //当ProcessRecord已经存在;
        //并且调用者不认为进程已经死亡,或者没有thread对象依附到该进程,这样我们就知道他不会crash;
        //该进程已经分配了pid,说明它正在启动或正在运行
        //这些情况下我们不需要做什么,直接返回
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                //我们已经启动了这个app,或者正在等待它启动(分配了pid但是没有thread依附),就keep it
                // 如果这是该进程中的一个新的package,那就添加到package列表
                app.addPackage(info.packageName, info.versionCode, mProcessStats);
                checkTime(startTime, "startProcess: done, added package to proc");
                return app;
            }

            // 如果ProcessRecord已经attach到先前的进程,那就清除它
            checkTime(startTime, "startProcess: bad proc running, killing");
            killProcessGroup(app.uid, app.pid);
            handleAppDiedLocked(app, true, true);
            checkTime(startTime, "startProcess: done killing old proc");
        }

        String hostingNameStr = hostingName != null
                ? hostingName.flattenToShortString() : null;

        if (app == null) {
            checkTime(startTime, "startProcess: creating new process record");
            // 创建新的Process Record对象
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            if (app == null) {
                return null;
            }
            app.crashHandler = crashHandler;
            checkTime(startTime, "startProcess: done creating new process record");
        } else {
            // 如果这是该进程中的一个新的package,那就添加到package列表
            app.addPackage(info.packageName, info.versionCode, mProcessStats);
            checkTime(startTime, "startProcess: added package to existing proc");
        }

        // 如果系统还没有准备就绪,那就暂停该进程启动,将当前进程加入到mProcessesOnHold,直到准备就绪
        if (!mProcessesReady
                && !isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mProcessesOnHold.contains(app)) {
                mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkTime(startTime, "startProcess: returning with proc on hold");
            return app;
        }

        checkTime(startTime, "startProcess: stepping in to startProcess");
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
}

经过上面重重判断后决定需要创建进程,继续走到startProcessLocked方法,这个方法在AMS里有4个重载的方法

其中的hostingType参数有”activity”,”service”,”broadcast”,”content provider”四个值
hostingNameStr数据类型为ComponentName,封装了组件的包名和自己的路径

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        long startTime = SystemClock.elapsedRealtime();
        //当app的pid大于0且不是当前进程的pid,则从mPidsSelfLocked中移除该app.pid
        if (app.pid > 0 && app.pid != MY_PID) {
            checkTime(startTime, "startProcess: removing from pids map");
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.remove(app.pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            checkTime(startTime, "startProcess: done removing from pids map");
            app.setPid(0);
        }

        //从mProcessesOnHold移除该app
        mProcessesOnHold.remove(app);

        checkTime(startTime, "startProcess: starting to update cpu stats");
        updateCpuStats();
        checkTime(startTime, "startProcess: done updating cpu stats");

        try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
                //当前package已被冻结,则抛出异常
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
                int[] permGids = null;
                try {
                    checkTime(startTime, "startProcess: getting gids from package manager");
                    //通过Package Manager获取gids
                    final IPackageManager pm = AppGlobals.getPackageManager();
                    permGids = pm.getPackageGids(app.info.packageName,
                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                    MountServiceInternal mountServiceInternal = LocalServices.getService(
                            MountServiceInternal.class);
                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
                            app.info.packageName);
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
                }


                 //添加APP和配置文件GID,以便app可以共享某些资源
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[2];
                } else {
                    gids = new int[permGids.length + 2];
                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
            }
            checkTime(startTime, "startProcess: building args");

            ......

            app.gids = gids;
            app.requiredAbi = requiredAbi;
            app.instructionSet = instructionSet;

            ......

            // 请求zygote创建进程,成功后会返回新进程的pid,否则会抛出异常
            //ProcessStartResult是Process内部类,封装了启动进程的结果
            //这是一个阻塞过程
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            checkTime(startTime, "startProcess: returned from zygote!");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

            ......

            //重置ProcessRecord的成员变量
            app.setPid(startResult.pid);
            app.usingWrapper = startResult.usingWrapper;
            app.removed = false;
            app.killed = false;
            app.killedByAm = false;
            checkTime(startTime, "startProcess: starting to update pids map");

            synchronized (mPidsSelfLocked) {
                ProcessRecord oldApp;
                // 如果已经有一个app占用了这个尚未清理的pid
                if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
                    // 清理与此pid相关联的内容   
                    cleanUpApplicationRecordLocked(oldApp, false, false, -1,
                            true /*replacingPid*/);
                }
                //将新创建的进程添加到mPidsSelfLocked
                this.mPidsSelfLocked.put(startResult.pid, app);
                if (isActivityProcess) {
                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                    msg.obj = app;
                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                }
            }
            checkTime(startTime, "startProcess: done updating pids map");
        } catch (RuntimeException e) {
            // 创建进程失败了,一个常见的情况是由于主动升级导致包被冻结
            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
        }
    }

这个方法中最重要的就是通过Process.start来创建应用进程,原理是通过socket通信告知Zygote进程fork子进程,创建新进程后将ActivityThread类加载到新进程,并调用ActivityThread.main()方法

静待更新

猜你喜欢

转载自blog.csdn.net/qq_30993595/article/details/81773286