图片 6

android组件工作过程-笔记

一. 概述

Android系统将经过做得很和谐的包装,对于上层app开垦者来讲进程大约是晶莹剔透的.
掌握Android的恋人,一定掌握Android四大组件,但对于经过恐怕会相对较目生.
叁个历程之中能够跑多个app(通过share uid的章程卡塔尔(قطر‎,
三个app也可以跑在两个经过里(通过配置Android:process属性卡塔尔(قطر‎.

再进一层进度是何等创立的, 或许过五人不明了fork的存在.
在本身的篇章知情Android进度创设流程 集中一些详细介绍了Process.start的进程是何等一步步成立进度.本文则是从另个角度来全局性解说Android进度运维全经过所关联的根脉,
先来探视AMS.startProcessLocked方法.

简书 编制程序之乐转发请评释原再次创下处,多谢!

Activity

Activity是显示型组件

startActivity will start a new activity,which will be placed at the top
of the activity stack.

startActivityResult will launch an activity and would return a result
when it finished.

  1. Activity.startActivityForResult
  2. Instrumentation.execStartActivity
  3. ActivityManagerProxy.startActivity
  4. ActivityManagerService.startActivity
  5. ActivityStack.startActivityMayWait
  6. ActivityStack.startActivityLocked
  7. ActivityStack.startActivityUncheckedLocked
  8. ActivityStack.resumeTopActivitiesLocked
  9. Activity.resumeTopActivityInnerLocked
  10. ActivityStack.startSpecificActivityLocked
  11. ActivityStack.realStartActivityLocked
  12. ApplicationThread.scheduleLaunchActivity
  13. sendMessage(LAUNCH_ACTIVITY)
  14. ActivityThread.handleLaunchActivity
  15. ActivityThread.performLaunchAcitvity
  16. MainActivity.onCreate

第一进程:

  1. Launcher通告AMS要求运营一个activity
  2. AMS成立叁个新的经过,然后运维三个ActivityThread实例
  3. ActivityThread把ApplicationThread给AMS
  4. AMS布告ActivityThread能够运营Activity了

涉及的class

  • Launcher:android启动器
  • Activity:Activity类,满含一个分子变量m
  • Instrumentation:重要用来监督应用程序和系统间的人机联作
  • ActivityMangerProxy:ActivityManagerService 的代理
  • ActivityStack: 描述叁个activity的库房
  • ApplicationThreadProxy:
  • ApplicationThread
  • ActivityThread:
  • ActivityManagerService:

ActivityManager框架

ActivityManager: Interact with the overall activities running in the
system.

图片 1

ActivityManager.png

ActivityManager在客户进度,施行操作的是在系统经过的AMS,从activityManager到ams是进程间通讯,

可以类比如aidl以了然,ActivityManagerProxy是代理类,抽象类ActivityManagerNative是Stub类,IActivityManager是aidl类,ams便是service类;

ActivityManager使用的是remote
proxy方式设计的,能够兑现跨进度的靶子访谈。

图片 2

image

本条图正是activityManager的实行的叁个进程图。

ActivityStack

State and management of a single stack of activities.
activity destroy ,pause,stop,
resumeTopActivityLocked:ensure the top activity is resumed

ActivityThread

This manages the execution of the main thread in an application process,
scheduling and executing activities, broadcasts, and other operations on
it as the activity manager requests.

主线程重要管理,调治,施行activity和broadcast的操作。

ActivityThread便是Application的主线程,主线程的非常重要权利是高速管理UI事件和布罗兹cast音信,
小心的是,View组件由主线程实践,故onDraw是在主线程的,而平板电脑View在后台线程。

android
app的入口是ActivityThread的main函数,这里做了那些事:创制Looper,Handler,ActivityThread,
ActivityThread的成员变量ApplicationThread是用来与AMS通信的,通讯方式是binder。

ApplicationThread

ApplicationThread继承ApplicationThreadNative,

Cast a Binder object into an application thread interface, generating a
proxy if needed.

ApplicationThreadNative实现了IApplicationThread,

System private API for communicating with the application. This is given
to the activity manager by an application when it starts up, for the
activity manager to tell the application about things it needs to do.

二. 四大组件与经过

依据上篇文章-
Launcher源码浅析,大家领会点击Launcher某些Logo后,会调用Launcher的startActivitySafely方法。如下:

service

Service是计算型组件

装饰情势的目标是为着方便扩大,能够动态的给三个目的增加一些别样的任务。
activity在startService的时候利用了那么些设计形式,
activity世袭子contextWrapper,wrapper里有个ContextImpl的mBase,最终会调到AcitvityManagerProxy的startService。接着通过binder,调用ams的start瑟维斯,

ActivityManagerService.startService
ActivityManagerService.startServiceLocked
ActivityManagerService.bringUpServiceLocked
ActivityManagerService.startProcessLocked
Process.start
ActivityThread.main
ActivityThread.attach
ActivityManagerProxy.attachApplication
ActivityManagerService.attachApplication
ActivityManagerService.attachApplicationLocked
ActivityManagerService.realStartServiceLocked
ApplicationThreadProxy.scheduleCreateService
ApplicationThread.scheduleCreateService
ActivityThread.queueOrSendMessage
H.sendMessage
H.handleMessage
ActivityThread.handleCreateService
ClassLoader.loadClass
Obtain Service
Service.onCreate

多少个步骤:
主进度调用到ams,创造新进度
新历程调用到ams,获取音讯
ams调用新进度,运维服务

2.1 startProcessLocked

ActivityManagerService.java有关运维进度有4个同名不一样参数的重载方法,
为了有助于说明,以下4个点子依次记为1(a),1(b)2(a)2(b) :

//方法 1(a)
final ProcessRecord startProcessLocked(
    String processName, ApplicationInfo info, boolean knownToBeDead,
    int intentFlags, String hostingType, ComponentName hostingName,
    boolean allowWhileBooting, boolean isolated, boolean keepIfLarge)

//方法 1(b)
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)

//方法 2(a)
private final void startProcessLocked(
    ProcessRecord app, String hostingType, String hostingNameStr)

//方法 2(b)
private final void startProcessLocked(
    ProcessRecord app, String hostingType, String hostingNameStr,
    String abiOverride, String entryPoint, String[] entryPointArgs)

1(aState of Qatar ==>
1(b卡塔尔国: 方法1(a卡塔尔将isolatedUid=0,别的参数赋值为null,再调用给1(b卡塔尔(قطر‎

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 */);
}

2(aState of Qatar ==> 2(b卡塔尔国: 方法2(a卡塔尔将其余3个参数abiOverride,entryPoint,
entryPointArgs赋值为null,再调用给2(b卡塔尔

private final void startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr) {
    startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
            null /* entryPoint */, null /* entryPointArgs */);
}

小结:

  • 1(a卡塔尔(قطر‎,1(b卡塔尔国的首先个参数为String类型的长河名processName,
  • 2(a卡塔尔, 2(bState of Qatar的首先个参数为ProcessRecord类型进度记录音讯ProcessRecord;
  • 1密密麻麻的方法最后调用到2雨后冬笋的方法;
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { boolean useLaunchAnimation = (v != null) && !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions : null; // Prepare intent intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (v != null) { intent.setSourceBounds(getViewBounds; } try { // ================== begin ====================== startActivity(intent, optsBundle); return true; } catch (ActivityNotFoundException|SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e); } return false;}

broadcast:

布罗兹castReceiver是音信型组件

广播的补益是能够不精通对方存在,那样能够裁减组件的耦合。
registerReceiver 进度解析:
AMS担当全体广播的登记和宣布,
ContextWrapper.registerReceiver
ContextImpl.registerReceiver
ActivityThread.getHandler
LoadedApk.getReceiverDispatcher
ActivityManagerProxy.registerReceiver

sendBroadcast过程:
ContextWrapper.sendBroadcast
ContextImpl.sendBroadcast
ActivityManagerProxy.broadcastIntent
ActivityManagerService.broadcastIntent
ActivityManagerService.broadcastIntentLocked
ActivityManagerService.scheduleBroadcastsLocked
Handler.sendEmptyMessage
ActivityManagerService.processNextBroadcast
ActivityManagerService.deliverToRegisteredReceiverLocked
ActivityManagerService.performReceiveLocked
ApplicationThreadProxy.scheduleRegisteredReceiver
ApplicaitonThread.scheduleRegisteredReceiver
InnerReceiver.performReceive
ReceiverDispatcher.performReceive
Handler.post
Args.run
BroadcastReceiver.onReceive

2.2 四大组件与经过

Activity, Service, ContentProvider,
布RhodescastReceiver那四大组件,在开发银行的进程,当其所承载的经过官样文章时须求先创制进度.
这几个成立进度的历程是调用前面讲到的startProcessLocked方法1(aState of Qatar . 调用流程:
1(a卡塔尔国 => 1(b卡塔尔 ==> 2(b卡塔尔.
下边再轻易说说那4大组件与经过创立是在哪一天供给成立的.

Launcher最后调用了父类 Activity 的startActivity(Intent intent, @Nullable
Bundle options卡塔尔国方法,startActivity又调用了startActivityForResult。

ContentProvider:

ContentProvider是数量分享型组件

ContentProvider下边使用的是Binder和无名分享内部存款和储蓄器机制。
http://blog.csdn.net/luoshengyang/article/details/6963418
ArticlesAdapter.getArticleCount
ContentResolver.acqireProvider
ApplicationContentResolve.acquireProvider
ActivityThread.acquireProvider
ActivityThread.getProvider
ActivityManagerService.getContentProvider
ActivityManagerService.getContentProviderImpl
ActivityManagerService.startProcessLocked
Process.start
ActivityThread.main
ActivityThread.attach
ActivityManagerService.attachApplication
ActivityManagerService.attachApplicationLocked
ApplicationThread.bindApplication
ActivityThread.handleBindApplication
ActivityThread.installContentProviders
ActivityThread.installProvider
ContentProvider.getIContentProvider
ContentProvider.attachInfo
ArticlesProvider.onCreate
ActivityMangerService.publishContentProviders
ActivityThread.installProvider

分享数据原理:
ContentProvider组件通过佚名分享内部存款和储蓄器机制落到实处,只用传输八个文书陈说符就能够。
http://blog.csdn.net/luoshengyang/article/details/6967204
ArticlesAdapter.getArticleByPos
ContentResolver.query
ContentResolver.acquireProvider
ApplicationContentResolver.acquireProvider
ActivityThread.acquireProvider
ActivityThread.getProvider
ContentProviderProxy.query
CursorWindow.native_init
CursorWindow.initBuffer
ContentProviderProxy.bulkQueryInternal
CursorWindow.writeToParcel
CursorWindow.native_getBinder
CursorWindow.getMemory
ContentProviderNative.onTransact
CursorWindow.CREATOR.createFromParcel
CursorWindow.native_init
CursorWindow.setMemory
Transport.bulkQuery
ArticlesProvider.query
SQLiteQueryBuilder.query
SQLiteDatabase.rawQueryWithFactory
SQLiteCursorDriver.query
AbstractWindowedCursor.setWindow
SQLiteCursor.getCount
QLiteCursor.fillWindow
SQLiteCursor.fillWindow

class :
ContentResolver
This class provides applications access to the content model.
CursorWindow:
A buffer containing multiple cursor rows.
A CursorWindow is read-write when initially created and used locally.
When sent to a remote process (by writing it to a Parcel), the remote
process receives a read-only view of the cursor window. Typically the
cursor window will be allocated by the producer, filled with data, and
then sent to the consumer for reading.

2.2.1 Activity

起步Activity进程:
调用startActivity,该形式通过层层调用,最后会调用ActivityStackSupervisor.java中的startSpecificActivityLocked,当activity所属进度尚未运行的景况下,则须求创制相应的进度.

[-> ActivityStackSupervisor.java]

void startSpecificActivityLocked(...) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    if (app != null && app.thread != null) {
        ...  //进程已创建的case
        return
    }
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
}

在startActivityForResult方法内,会调用Instrumentation的execStartActivity方法。

2.2.2 Service

启航服务进程:
调用startService,该格局通过层层调用,最终会调用ActiveServices.java中的bringUpServiceLocked,当Service进度未有运行的意况(app==null卡塔尔,
则必要创建相应的进程. 更多关于Service,
见start瑟维斯流程深入分析

[-> ActiveServices.java]

private final String bringUpServiceLocked(...){
    ...
    ProcessRecord app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
    if (app == null) {
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            ...
        }
    }
    ...
}

注: 这里的mInstrumentation是Launcher里面的。

2.2.3 ContentProvider

ContentProvider管理进度: 调用ContentResolver.query该措施通过层层调用,
最后会调用到AMS.java中的getContentProviderImpl,当ContentProvider所对应进度空头支票,则供给创制新进度.
更加多关于ContentProvider,见理解ContentProvider原理(一)

[-> AMS.java]

private final ContentProviderHolder getContentProviderImpl(...) {
    ...
    ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false);
    if (proc != null && proc.thread != null) {
        ...  //进程已创建的case
    } else {
        proc = startProcessLocked(cpi.processName,
                    cpr.appInfo, false, 0, "content provider",
                    new ComponentName(cpi.applicationInfo.packageName,cpi.name),
                    false, false, false);
    }
    ...
}
 public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) { Uri referrer = onProvideReferrer(); if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); } options = transferSpringboardActivityOptions; Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, who, requestCode, ar.getResultCode(), ar.getResultData; } cancelInputsAndStartExitTransition; }

2.2.4 Broadcast

广播管理进程: 调用send布罗兹cast,该情势通过层层调用,
最终会调用到BroadcastQueue.java中的processNextBroadcast,当布RhodescastReceiver所对应的长河未有运营,则开创相应进程.
越多关于broadcast, 见Android
布罗兹cast广播机制解析.

[-> BroadcastQueue.java]

final void processNextBroadcast(boolean fromMsg) {
    ...
    ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
        info.activityInfo.applicationInfo.uid, false);
    if (app != null && app.thread != null) {
        ...  //进程已创建的case
        return
    }

    if ((r.curApp=mService.startProcessLocked(targetProcess,
            info.activityInfo.applicationInfo, true,
            r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
            "broadcast", r.curComponent,
            (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
                    == null) {
        ...
    }
    ...
}

startActivityForResult里面调用了mInstrumentation.execStartActivity方法

2.3 小节

Activity, 瑟维斯, ContentProvider,
布罗兹castReceiver那四大组件在运行时,当所承载的长河不设一时,都急需创制.
进度的创建进程交由系统经过system_server来成功的.

图片 3

简称:

  • ATP: ApplicationThreadProxy
  • AT: ApplicationThread (继承于ApplicationThreadNative)
  • AMP: ActivityManagerProxy
  • AMS: ActivityManagerService (继承于ActivityManagerNative)

图解:

  1. system_server进度中调用startProcessLocked主意,该格局最后经过socket格局,将必要创建新进度的信息告诉Zygote进度,并拥塞等待Socket重临新创设进度的pid;
  2. Zygote进度采纳到system_server发送过来的消息,
    则通过fork的艺术,将zygote自己进度复制生成新的长河,并将ActivityThread相关的能源加载到新历程app
    process,这几个历程大概是用以承载activity等零零部件;
  3. 创设完新进度后fork再次回到若干遍, 在新进度app
    process向servicemanager查询system_server进度中binder服务端AMS,获取绝对应的Client端,也正是AMP.
    有了这一对binder c/s对, 那么app
    process便得以经过binder向跨进度system_server发送央求,即attachApplication(卡塔尔(قطر‎
  4. system_server进程接受到相应binder操作后,经过数十次调用,利用蛋氨酸酸向app
    process发送binder诉求, 即bindApplication.

system_server具备硫胺素酸/AMS,
每三个新成立的经过都会有三个相应的AT/AMS,进而得以跨进程 实行人机联作通信.
那就是经过创制进程的一体化生态链.

四大组件的经过创建时机:

组件 创建方法
Activity ASS.startSpecificActivityLocked()
Service ActiveServices.bringUpServiceLocked()
ContentProvider AMS.getContentProviderImpl()
Broadcast BroadcastQueue.processNextBroadcast()
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { ... }

三. 进度运行全经过

日前刚已介绍四大组件的创立进度的历程是调用1(a卡塔尔国 startProcessLocked主意,该方法会再调用1(b卡塔尔(قطر‎方法.
接下去从该情势早先往下叙述.

里头有个参数是mMainThread.getApplicationThread(卡塔尔,mMainThread是Activity类的成员变量(ActivityThread类型),mMainThread.getApplicationThread(State of Qatar获取的是ApplicationThread类型,ApplicationThread则是ActivityThread的里边类,能够见见ApplicationThread是一个Binder对象。

3.1 AMS.startProcessLocked

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
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);

        if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
            //如果当前处于后台进程,检查当前进程是否处于bad进程列表
            if (mBadProcesses.get(info.processName, info.uid) != null) {
                return null;
            }
        } else {
            //当用户明确地启动进程,则清空crash次数,以保证其不处于bad进程直到下次再弹出crash对话框。
            mProcessCrashTimes.remove(info.processName, info.uid);
            if (mBadProcesses.get(info.processName, info.uid) != null) {
                mBadProcesses.remove(info.processName, info.uid);
                if (app != null) {
                    app.bad = false;
                }
            }
        }
    } else {
        //对于孤立进程,无法再利用已存在的进程
        app = null;
    }

    //当存在ProcessRecord,且已分配pid(正在启动或者已经启动),
    // 且caller并不认为该进程已死亡或者没有thread对象attached到该进程.则不应该清理该进程
    if (app != null && app.pid > 0) {
        if (!knownToBeDead || app.thread == null) {
            //如果这是进程中新package,则添加到列表
            app.addPackage(info.packageName, info.versionCode, mProcessStats);
            return app;
        }
        //当ProcessRecord已经被attached到先前的一个进程,则杀死并清理该进程
        killProcessGroup(app.info.uid, app.pid);
        handleAppDiedLocked(app, true, true);
    }

    String hostingNameStr = hostingName != null? hostingName.flattenToShortString() : null;
    if (app == null) {
        // 创建新的Process Record对象
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            return null;
        }
        app.crashHandler = crashHandler;
    } else {
        //如果这是进程中新package,则添加到列表
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
    }
    //当系统未准备完毕,则将当前进程加入到mProcessesOnHold
    if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) {
        if (!mProcessesOnHold.contains(app)) {
            mProcessesOnHold.add(app);
        }
        return app;
    }
    // 启动进程【见小节3.2】
    startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    return (app.pid != 0) ? app : null;
}

首要效用:

  • 对此非isolated进程,则依照进度名和uid来询问相应的ProcessRecord构造体.
    即便当前历程处于后台且当前进程处于mBadProcesses列表,则一向回到;不然清空crash次数,以管教其不处在bad进度直到后一次再弹出crash对话框。
  • 当存在ProcessRecord,且已分配pid(正在运营或许曾经运行卡塔尔的情状下
    • 当caller并不以为该进度已断气依旧还没thread对象attached到该进度.则不应有清理该进程,则直接回到;
    • 再不杀死并清理该进程;
  • 当ProcessRecord为空则新建一个,当创设失利则一向回到;
  • 当系统未计划甘休,则将方今经过步入到mProcessesOnHold, 并直接回到;
  • 提及底运营新进度,个中参数含义:
    • hostingType可取值为”activity”,”service”,”broadcast”,”content
      provider”;
    • hostingNameStr数据类型为ComponentName,代表的是切实可行相对应的零件名.

其它,
进度的uid是在进程真正创立之前调用newProcessRecordLocked形式来博取的uid,
这里会虚构是否为isolated的意况.

为了后边研讨的方便,有无法缺乏提前证实下将在现身的那多少个类的关联,它们各自是

3.2 AMS.startProcessLocked

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) {
        synchronized (mPidsSelfLocked) {
            mPidsSelfLocked.remove(app.pid);
            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        }
        app.setPid(0);
    }
    //从mProcessesOnHold移除该app
    mProcessesOnHold.remove(app);
    updateCpuStats(); //更新cpu统计信息
    try {
        try {
            if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
                //当前package已被冻结,则抛出异常
                throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
            }
        } 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 {
                //通过Package Manager获取gids
                final IPackageManager pm = AppGlobals.getPackageManager();
                permGids = pm.getPackageGids(app.info.packageName, app.userId);
                MountServiceInternal mountServiceInternal = LocalServices.getService(
                        MountServiceInternal.class);
                mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
                        app.info.packageName);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            //添加共享app和gids,用于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));
        }

        //根据不同参数,设置相应的debugFlags
        ...

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

        boolean isActivityProcess = (entryPoint == null);
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        //请求Zygote创建新进程[见3.3]
        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);

        ...
        if (app.persistent) {
            Watchdog.getInstance().processStarted(app.processName, startResult.pid);
        }
        //重置ProcessRecord的成员变量
        app.setPid(startResult.pid);
        app.usingWrapper = startResult.usingWrapper;
        app.removed = false;
        app.killed = false;
        app.killedByAm = false;

        //将新创建的进程加入到mPidsSelfLocked
        synchronized (mPidsSelfLocked) {
            this.mPidsSelfLocked.put(startResult.pid, app);
            if (isActivityProcess) {
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                //延迟发送消息PROC_START_TIMEOUT_MSG
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        }
    } catch (RuntimeException e) {
        app.setPid(0); //进程创建失败,则重置pid
    }
}
  • 依照分化参数,设置相应的debugFlags,举例在AndroidManifest.xml中装置androidd:debuggable为true,代表app运转在debug情势,则扩张debugger标记甚至开启JNI
    check作用
  • 调用Process.start来成立新历程;
  • 重新载入参数ProcessRecord的积极分子变量,
    日常景观下超时10s后发送PROC_START_TIMEOUT_MSG的handler消息;

关于Process.start(卡塔尔(قطر‎是透过socket通讯告知Zygote创造fork子进度,创制新历程后将ActivityThread类加载到新历程,并调用ActivityThread.main(卡塔尔(قطر‎方法。详细进程见知道Android进程创设流程,接下去步入AT.main方法.

  1. IApplicationThread
  2. ApplicationThread
  3. ApplicationThreadNative
  4. ApplicationThreadProxy

3.3 ActivityThread.main

[-> ActivityThread.java]

public static void main(String[] args) {
    //性能统计默认是关闭的
    SamplingProfilerIntegration.start();
    //将当前进程所在userId赋值给sCurrentUser
    Environment.initForCurrentUser();

    EventLogger.setReporter(new EventLoggingReporter());
    AndroidKeyStoreProvider.install();

    //确保可信任的CA证书存放在正确的位置
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");

    //创建主线程的Looper对象, 该Looper是不运行退出
    Looper.prepareMainLooper();

    //创建ActivityThread对象
    ActivityThread thread = new ActivityThread();

    //建立Binder通道 【见流程3.4】
    thread.attach(false);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    // 当设置为true时,可打开消息队列的debug log信息
    if (false) {
        Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
    }
    Looper.loop(); //消息循环运行
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
  • 创建主线程的Looper对象: 该Looper是不运转退出.
    也正是说主线程的Looper是在进程制造实现时自动成立达成,假设子线程也急需创设handler通讯进程,那么就须求手动创立Looper对象,並且每个线程只可以创立一次.
  • 创建ActivityThread对象thread = new ActivityThread():
    该进程会最早化多少个很主要的变量:

    • mAppThread = new ApplicationThread()
    • mLooper = Looper.myLooper()
    • mH = new H(), H继承于Handler;用于拍卖组件的人命周期.
  • attach进程是最近主线程向system_server进度通讯的历程,
    将thread新闻告知AMS.接下来还有恐怕会愈发验证该进度.
  • sMainThreadHandler通过getHandler(State of Qatar,获取的靶子便是mH,那便是主线程的handler对象.

随后主线程调用Looper.loop(卡塔尔(قطر‎,步向音信循环情状,
当未有音讯时主线程步入休眠状态,
一旦有音讯赶到则提醒主线程并实行相关操作.

一旦您查看过AIDL生成的文书,那么那多少个类就相比比较简单于理解了,IApplicationThread相当于AIDL接口

3.4. ActivityThread.attach

[-> ActivityThread.java]

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
         //开启虚拟机的jit即时编译功能
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());

        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        //创建ActivityManagerProxy对象
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            //调用基于IActivityManager接口的Binder通道【见流程3.5】
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
        }

        //观察是否快接近heap的上限
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    mSomeActivitiesChanged = false;
                    try {
                        //当已用内存超过最大内存的3/4,则请求释放内存空间
                        mgr.releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                    }
                }
            }
        });
    } else {
        ...
    }
    //添加dropbox日志到libcore
    DropBox.setReporter(new DropBoxReporter());

    //添加Config回调接口
    ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            synchronized (mResourcesManager) {
                if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                    if (mPendingConfiguration == null ||
                            mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                        mPendingConfiguration = newConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, newConfig);
                    }
                }
            }
        }
        @Override
        public void onLowMemory() {
        }
        @Override
        public void onTrimMemory(int level) {
        }
    });
}

对此非系统attach的拍卖流程:

  • 开创线程来展开设想机的jit即时编写翻译;
  • 因而binder, 调用到AMS.attachApplication,
    其参数mAppThread的数据类型为ApplicationThread
  • 调查是不是快周边heap的上限,当已用内部存款和储蓄器抢先最大内存的3/4,则要求释放内部存款和储蓄器空间
  • 添加dropbox日志到libcore
  • 增添Config回调接口
class ApplicationThread extends ApplicationThreadNative { // 因为ApplicationThreadNative继承 Binder,且ApplicationThreadNative是抽象类,所以ApplicationThread才是真正的Binder实现。}public abstract class ApplicationThreadNative extends Binder implements IApplicationThread { // Activity中常用到的那个获取接口的方法如:ServiceConnection中 IMedia iMedia = IMedia.Stub.asInterface; static public IApplicationThread asInterface(IBinder obj) { // 内部代理类 return new ApplicationThreadProxy;}

3.5 AMP.attachApplication

[-> ActivityManagerProxy.java]

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); //【见流程3.6】
    reply.readException();
    data.recycle();
    reply.recycle();
}

此处 descriptor = “android.app.IActivityManager”

看下那个AIDL接口的一部分概念,在那之中前边要用到。

3.6 AMN.onTransact

[-> ActivityManagerNative.java]

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    ...
     case ATTACH_APPLICATION_TRANSACTION: {
        data.enforceInterface(IActivityManager.descriptor);
        //获取ApplicationThread的binder代理类 ApplicationThreadProxy
        IApplicationThread app = ApplicationThreadNative.asInterface(
                data.readStrongBinder());
        if (app != null) {
            attachApplication(app); //此处是ActivityManagerService类中的方法 【见流程3.7】
        }
        reply.writeNoException();
        return true;
    }
    }
}
public interface IApplicationThread extends IInterface { void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException; void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException; void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException; void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException; void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs) throws RemoteException; void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException; void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config) throws RemoteException; void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) throws RemoteException; void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments, IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection, int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) throws RemoteException;

3.7 AMS.attachApplication

[-> ActivityManagerService.java]

public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid); // 【见流程3.8】
        Binder.restoreCallingIdentity(origId);
    }
}

此处的thread便是ApplicationThreadProxy对象,用于前面边通过Process.start(卡塔尔国所创办的长河中ApplicationThread对象实行通讯.

注意mMainThread在Launcher中,且mMainThread变量也是在Activity.attach(State of Qatar中绑定的。最近大家利用到的一些变量如(mMainThread,mInstrumentation)都以Launcher中早已初阶化好的,但大家今天禀析的是Launcher运维第三方Activity并非Launcher本身,后边我们会另行相见这几个变量,那些变量的初始化和绑定进程会并发在新Activity的成立中,方今先不要对那几个变量的由来吸引!

3.8 AMS.attachApplicationLocked

[-> ActivityManagerService.java]

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    ProcessRecord app;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord
        }
    } else {
        app = null;
    }
    if (app == null) {
        if (pid > 0 && pid != MY_PID) {
            //ProcessRecord为空,则杀掉该进程
            Process.killProcessQuiet(pid);
        } else {
            //退出新建进程的Looper
            thread.scheduleExit();
        }
        return false;
    }

    //还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }

    final String processName = app.processName;
    try {
        //绑定死亡通知
        AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        startProcessLocked(app, "link fail", processName); //重新启动进程
        return false;
    }

    //重置进程信息
    app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空
    app.curAdj = app.setAdj = -100;
    app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.forcingToForeground = null;
    updateProcessForegroundLocked(app, false, false);
    app.hasShownUi = false;
    app.debugging = false;
    app.cached = false;
    app.killedByAm = false;
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息

    //系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;

    //app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
    if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
        Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
        msg.obj = app;
        mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
    }

    try {
        ...
        ensurePackageDexOpt(app.instrumentationInfo != null
                ? app.instrumentationInfo.packageName
                : app.info.packageName);

        ApplicationInfo appInfo = app.instrumentationInfo != null
                ? app.instrumentationInfo : app.info;
        ...
        // 绑定应用 [见流程3.9]
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());
        //更新进程LRU队列
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        app.resetPackageList(mProcessStats);
        app.unlinkDeathRecipient();
        //每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启
        startProcessLocked(app, "bind fail", processName);
        return false;
    }

    mPersistentStartingProcesses.remove(app);
    mProcessesOnHold.remove(app);
    boolean badApp = false;
    boolean didSomething = false;

    //Activity: 检查最顶层可见的Activity是否等待在该进程中运行
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }

    //Service: 寻找所有需要在该进程中运行的服务
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }

    //Broadcast: 检查是否在这个进程中有下一个广播接收者
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            badApp = true;
        }
    }
    //检查是否在这个进程中有下一个backup代理
    if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
        ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        } catch (Exception e) {
            badApp = true;
        }
    }
    if (badApp) { //杀掉bad应用
        app.kill("error during init", true);
        handleAppDiedLocked(app, false, true);
        return false;
    }
    if (!didSomething) {
        updateOomAdjLocked(); //更新adj的值
    }
    return true;
}
  1. 根据pid从mPidsSelfLocked中查询到对应的ProcessRecord对象app;
  2. 当app==null,意味着此次成立的进度子虚乌有, 则间接再次来到.
  3. 还刚进去attach进度,这时thread应为null,若不为null则表示该app附到上贰个经过,则调用handleAppDied洛克d清理.
  4. 绑定命丧黄泉公告,当进度pid驾鹤归西时会通过binder过逝回调,来布告system_server进度一了百了的新闻;
  5. 重新载入参数ProcessRecord进度消息, 那时候app.thread也付与了新值,便不再为空.
  6. app进度存在正在起步中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
  7. 调用thread.bindApplication绑定应用进程, 前边再进一层表明
  8. 拍卖Provider, Activity, Service, 布罗兹cast相应流程

下边,再来讲说thread.bindApplication的进程.

Instrumentation
仪表盘那些也是老大关键的贰个类,大约对这么些类某些驾驭,不然后面很难掌握。

3.9 ATP.bindApplication

[-> ApplicationThreadNative.java ::ApplicationThreadProxy]

class ApplicationThreadProxy implements IApplicationThread {
    ...
    public final void bindApplication(String packageName, ApplicationInfo info,
            List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,
            Bundle testArgs, IInstrumentationWatcher testWatcher,
            IUiAutomationConnection uiAutomationConnection, int debugMode,
            boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
            Bundle coreSettings) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeString(packageName);
        info.writeToParcel(data, 0);
        data.writeTypedList(providers);
        if (testName == null) {
            data.writeInt(0);
        } else {
            data.writeInt(1);
            testName.writeToParcel(data, 0);
        }
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        data.writeBundle(testArgs);
        data.writeStrongInterface(testWatcher);
        data.writeStrongInterface(uiAutomationConnection);
        data.writeInt(debugMode);
        data.writeInt(openGlTrace ? 1 : 0);
        data.writeInt(restrictedBackupMode ? 1 : 0);
        data.writeInt(persistent ? 1 : 0);
        config.writeToParcel(data, 0);
        compatInfo.writeToParcel(data, 0);
        data.writeMap(services);
        data.writeBundle(coreSettings);
        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
    ...
}

ATP经过binder ipc传递到ATN的onTransact过程.

mInstrumentation是Activity的四个分子变量,且mInstrumentation是在Activity的
attach方法里面赋值的,这几个方式老大首要,里面还应该有mWindow = new PhoneWindow(this, window, activityConfigCallback);等操作。前面会深入分析到此办法。

3.10 ATN.onTransact

[-> ApplicationThreadNative.java]

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    ...
    case BIND_APPLICATION_TRANSACTION:
    {
        data.enforceInterface(IApplicationThread.descriptor);
        String packageName = data.readString();
        ApplicationInfo info =
            ApplicationInfo.CREATOR.createFromParcel(data);
        List<ProviderInfo> providers =
            data.createTypedArrayList(ProviderInfo.CREATOR);
        ComponentName testName = (data.readInt() != 0)
            ? new ComponentName(data) : null;
        ProfilerInfo profilerInfo = data.readInt() != 0
                ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
        Bundle testArgs = data.readBundle();
        IBinder binder = data.readStrongBinder();
        IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
        binder = data.readStrongBinder();
        IUiAutomationConnection uiAutomationConnection =
                IUiAutomationConnection.Stub.asInterface(binder);
        int testMode = data.readInt();
        boolean openGlTrace = data.readInt() != 0;
        boolean restrictedBackupMode = (data.readInt() != 0);
        boolean persistent = (data.readInt() != 0);
        Configuration config = Configuration.CREATOR.createFromParcel(data);
        CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
        HashMap<String, IBinder> services = data.readHashMap(null);
        Bundle coreSettings = data.readBundle();
        //[见流程3.11]
        bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,
                testWatcher, uiAutomationConnection, testMode, openGlTrace,
                restrictedBackupMode, persistent, config, compatInfo, services, coreSettings);
        return true;
    }
    ...
}

Instrumentation
仪表盘,命名就恍如处理生命周期相通,事实也基本上如此。看下Instrumentation
的机要格局:

3.11 AT.bindApplication

[-> ActivityThread.java ::ApplicationThread]

public final void bindApplication(String processName, ApplicationInfo appInfo,
        List<ProviderInfo> providers, ComponentName instrumentationName,
        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
        IInstrumentationWatcher instrumentationWatcher,
        IUiAutomationConnection instrumentationUiConnection, int debugMode,
        boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
        Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
        Bundle coreSettings) {

    if (services != null) {
        //将services缓存起来, 减少binder检索服务的次数
        ServiceManager.initServiceCache(services);
    }

    //发送消息H.SET_CORE_SETTINGS
    setCoreSettings(coreSettings);

    IPackageManager pm = getPackageManager();
    android.content.pm.PackageInfo pi = null;
    try {
        pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
    } catch (RemoteException e) {
    }
    if (pi != null) {
        boolean sharedUserIdSet = (pi.sharedUserId != null);
        boolean processNameNotDefault = (pi.applicationInfo != null &&
         !appInfo.packageName.equals(pi.applicationInfo.processName));
        boolean sharable = (sharedUserIdSet || processNameNotDefault);

        if (!sharable) {
            VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
                                    appInfo.processName);
        }
    }

    //初始化AppBindData, 再发送消息H.BIND_APPLICATION
    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableOpenGlTrace = enableOpenGlTrace;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    sendMessage(H.BIND_APPLICATION, data);
}

其间setCoreSettings(卡塔尔(قطر‎进程正是调用sendMessage(H.SET_CORE_SETTINGS,
coreSettings卡塔尔来向主线程发送SET_CORE_SETTINGS音讯.bindApplication方法的尤为重要成效是逐一贯主线程发送音讯H.SET_CORE_SETTINGSH.BIND_APPLICATION.
接下去再来讲说那七个新闻的处理进度

execStartActivitycallApplicationOnCreatenewActivitycallActivityOnCreatecallActivityOnDestroycallActivityOnRestoreInstanceStatecallActivityOnPostCreatecallActivityOnNewIntentcallActivityOnStartcallActivityOnRestartcallActivityOnResumecallActivityOnStopcallActivityOnSaveInstanceStatecallActivityOnPausecallActivityOnUserLeaving

3.12 H.SET_CORE_SETTINGS

[-> ActivityThread.java ::H]

当主线程收到H.SET_CORE_SETTINGS,则调用handleSetCoreSettings

private void handleSetCoreSettings(Bundle coreSettings) {
    synchronized (mResourcesManager) {
        mCoreSettings = coreSettings;
    }
    onCoreSettingsChange();
}

private void onCoreSettingsChange() {
    boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
    if (debugViewAttributes != View.mDebugViewAttributes) {
        View.mDebugViewAttributes = debugViewAttributes;

        // 由于发生改变, 请求所有的activities重启启动
        for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
            requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);
        }
    }
}

mInstrumentation.execStartActivity内部调用了ActivityManagerNative.getDefault(卡塔尔国.startActivity(卡塔尔国方法。如下:

3.13 H.BIND_APPLICATION

[-> ActivityThread.java ::H]

当主线程收到H.BIND_APPLICATION,则调用handleBindApplication

private void handleBindApplication(AppBindData data) {

    mBoundApplication = data;
    mConfiguration = new Configuration(data.config);
    mCompatConfiguration = new Configuration(data.config);

    ...

    //设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名
    Process.setArgV0(data.processName);
    android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());

    if (data.persistent) {
        //低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量
        if (!ActivityManager.isHighEndGfx()) {
            HardwareRenderer.disable(false);
        }
    }

    //重置时区
    TimeZone.setDefault(null);
    Locale.setDefault(data.config.locale);

    //更新系统配置
    mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
    mCurDefaultDisplayDpi = data.config.densityDpi;
    applyCompatConfiguration(mCurDefaultDisplayDpi);

    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    ...

    // 创建ContextImpl上下文
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    if (!Process.isIsolated()) {
        final File cacheDir = appContext.getCacheDir();
        if (cacheDir != null) {
            System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
        }

        //用于存储产生/编译的图形代码
        final File codeCacheDir = appContext.getCodeCacheDir();
        if (codeCacheDir != null) {
            setupGraphicsSupport(data.info, codeCacheDir);
        }
    }

    final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
    DateFormat.set24HourTimePref(is24Hr);

    View.mDebugViewAttributes =  mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
    ...

    //当处于调试模式,则运行应用生成systrace信息
    boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    Trace.setAppTracingAllowed(appTracingAllowed);

    //初始化 默认的http代理
    IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
    if (b != null) {
        IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
        final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
        Proxy.setHttpProxySystemProperty(proxyInfo);
    }

    if (data.instrumentationName != null) {
        InstrumentationInfo ii = null;
        ii = appContext.getPackageManager().getInstrumentationInfo(data.instrumentationName, 0);

        mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        mInstrumentationSplitAppDirs = ii.splitSourceDirs;
        mInstrumentationLibDir = ii.nativeLibraryDir;
        mInstrumentedAppDir = data.info.getAppDir();
        mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
        mInstrumentedLibDir = data.info.getLibDir();

        ApplicationInfo instrApp = new ApplicationInfo();
        instrApp.packageName = ii.packageName;
        instrApp.sourceDir = ii.sourceDir;
        instrApp.publicSourceDir = ii.publicSourceDir;
        instrApp.splitSourceDirs = ii.splitSourceDirs;
        instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
        instrApp.dataDir = ii.dataDir;
        instrApp.nativeLibraryDir = ii.nativeLibraryDir;
        LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
        ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

        java.lang.ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();

        mInstrumentation.init(this, instrContext, appContext,
               new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
               data.instrumentationUiAutomationConnection);
        ...
    } else {
        mInstrumentation = new Instrumentation();
    }

    //FLAG_LARGE_HEAP则清除内存增长上限
    if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
    } else {
        dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
    }

    try {
        // 通过反射,创建目标应用Application对象,即在AndroidManifest.xml文件定义的应用名
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;

        if (!data.restrictedBackupMode) {
            List<ProviderInfo> providers = data.providers;
            if (providers != null) {
                installContentProviders(app, providers);
                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
            }
        }

        mInstrumentation.onCreate(data.instrumentationArgs);
        //调用Application.onCreate()回调方法.
        mInstrumentation.callApplicationOnCreate(app);

    } finally {
        StrictMode.setThreadPolicy(savedPolicy);
    }
}

小节: 到此进程运行的全经过基本介绍完, 那接下去程序该往哪执行吗,
那正是要三番四遍看[见流程3.8] AMS.attachApplicationLocked.从[3.9 ~ 3.13]
只是介绍了bindApplication进程,
该形式之后正是组件运维相关的内容,本文首要将经过有关内容,
组件的剧情后续还有也许会再进一层介绍.

 public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { // ... IApplicationThread whoThread = (IApplicationThread) contextThread; try { 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; }

四. 总结

正文首先介绍AMS的4个同名差异参数的措施startProcessLocked;
紧接着陈述了四大组件与经过的关联, Activity, Service, ContentProvider,
布罗兹castReceiver那四大组件,在起步的经过,当其所承载的经过不设有的时候须要先成立进程.
再接下来步向入眼以startProcessLocked以引线一路教授整个经过所蒙受的主干方法.
在一切进度中有新成立的进程与system_server进程之间的互相进度是通过binder实行通讯的, 这里有两条binder通道分别为AMP/AMN 和 甲状腺素酸/ATN.

图片 4

上海体育场所正是叁遍完整的历程创立进程,app的别样组件需求有二个承继其运维的器皿,那便是经过,
那么进度的创导进度都以由系统经过system_server通过socket向zygote进度来呼吁fork(卡塔尔(قطر‎新进度,
当成立出来的app process与system_server进度之间的通讯便是经过binder
IPC机制.

ActivityManagerNative.getDefault(卡塔尔(قطر‎是个什么东西,那就是后面为啥要提一下ApplicationThread的由来了,情势大概一致。同样看上边多少个类:

  1. IActivityManager
  2. ActivityManagerService
  3. ActivityManagerNative
  4. ActivityManagerProxy和日前完全对应,AMS闪亮上台。很显眼,AMS是真正Binder的达成类。

为了反映AMS的要害和更加好通晓Binder,这里的机要部分的代码多贴一些,我们开采和ApplicationThread格局差非常的少完全一样,何况IActivityManager正是AIDL的接口,而ActivityManagerNative
世襲自Binder 且是空洞的,真正的兑现是AMS,那么AMS类在哪个地方吧?

ActivityManagerNative 有一个静态的getDefault方法,依照类加运载飞机制
,类在调用static方法时候才会初步化,当时回来gDefault.get(卡塔尔;
Singleton是Android的三个单例封装类工具类,第三回调用get方法时候会经过create方法最早化AMS对象。

其一单例写法很有意思,又GET二个技术。

public abstract class Singleton<T> { private T mInstance; protected abstract T create(); public final T get() { synchronized  { if (mInstance == null) { mInstance = create(); } return mInstance; } }}

IBinder b = ServiceManager.getService("activity");那一个Binder对象正是ActivityManagerService。

在线 ActivityManagerService.java

public abstract class ActivityManagerNative extends Binder implements IActivityManager{ /** * Cast a Binder object into an activity manager interface, generating * a proxy if needed. */ 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; } /** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { return gDefault.get(); } public IBinder asBinder() { return this; } private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if  { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface; if  { Log.v("ActivityManager", "default service = " + am); } return am; } };}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 { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder; data.writeString(callingPackage); intent.writeToParcel; data.writeString(resolvedType); data.writeStrongBinder; data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); if (profilerInfo != null) { data.writeInt; profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt; } if (options != null) { data.writeInt; options.writeToParcel; } else { data.writeInt; } mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } // .............. // .............. // }

回顾看下 IActivityManager 接口的一对注脚:

public interface IActivityManager extends IInterface { public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException; public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException; public int startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity, int userId) throws RemoteException; public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException; public int startActivityWithConfig(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration newConfig, Bundle options, int userId) throws RemoteException; public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) throws RemoteException; public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, Intent intent, String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException; public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options) throws RemoteException; public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException; public boolean finishActivity(IBinder token, int code, Intent data, int finishTask) throws RemoteException; public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException; public boolean finishActivityAffinity(IBinder token) throws RemoteException; public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException; public boolean releaseActivityInstance(IBinder token) throws RemoteException; public void releaseSomeActivities(IApplicationThread app) throws RemoteException; public boolean willActivityBeVisible(IBinder token) throws RemoteException; public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String requiredPermission, int userId) throws RemoteException; public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException; public int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String[] requiredPermissions, int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException; public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast, int flags) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; public void activityResumed(IBinder token) throws RemoteException;

我们跟着上一步ActivityManagerNative.getDefault(State of Qatar.startActivity(卡塔尔(قطر‎即AMS(ActivityManagerService).startActivity();

 @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; }

AMS的startActivity方法调用了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); }

上面是一琳琅满指标调用关系

1. AMS.startActivityAsUser-> ActivityStarter.startActivityMayWait2. ActivityStarter.startActivityMayWait -> ActivityStarter.startActivityLocked3. ActivityStarter.startActivityLocked -> ActivityStarter.doPendingActivityLaunchesLocked4. ActivityStarter.doPendingActivityLaunchesLocked -> ActivityStarter.startActivityUnchecked5. ActivityStarter.startActivityUnchecked -> mSupervisor(ActivityStackSupervisor).resumeFocusedStackTopActivityLocked();6. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked->.targetStack(ActivityStack).resumeTopActivityUncheckedLocked7. ActivityStack.resumeTopActivityUncheckedLocked -> ActivityStack.resumeTopActivityInnerLocked8. ActivityStack.resumeTopActivityInnerLocked -> mStackSupervisor(ActivityStackSupervisor).startSpecificActivityLocked9. ActivityStackSupervisor.startSpecificActivityLocked -> ActivityStackSupervisor.realStartActivityLocked

这段调用进程当成非常复杂,大致每一种类或方法都是千百行,绕的自己快晕了。这几个流程,会筛选着代码批注,若是各类流程一下子把代码贴出来,大约都会被搞疯。

先看下最终一步:ActivityStackSupervisor.startSpecificActivityLocked

 void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime; if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { // Don't add this if it is a platform component that is marked // to run in multiple processes, because this is actually // part of the framework so doesn't make sense to track as a // separate apk in the process. app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString; } // If a dead object exception was thrown -- fall through to // restart the application. } // mService是AMS mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }

tips:在 AMS中,每三个 Activity 组件都有三个顾客 ID
和几个经过名称,个中,客户 ID 是在装置该 Activity 组件时由
PackageManagerService 分配的,而经过名称则是由该 Activity 组件的
android:process属性来支配的。ActivityManagerService 在起步叁个Activity 组件时,首先会以它的客户 ID
和经过名称来检查系统中是或不是留存一个心心相印的应用程序进度。假若存在,就能直接文告那些应用程序进度将
Activity 组件运营起来;不然,就能先以这一个客户 ID
和进程名称来创设一个应用程序进程,然后在通知那些应用程序进度将该
Activity 组件运转起来。

事务所方if语句的推断:. if (app != null && app.thread != null卡塔尔国 {
}假如app已经运转,则透过realStartActivityLocked(State of Qatar运转Activity。.
假如app还没有运维,则经过AMS创立应用进度。

上述代码第三遍开发银行必定先运维

查看ActivityManager瑟维斯类的
startProcessLocked(卡塔尔(قطر‎方法,注意startProcessLocked方法有多少个重载上边包车型地铁办法调用app
= newProcessRecordLocked,最终又调用了另四个重载方法startProcessLocked。

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) { // 传入的 isolated 参数为 false ,if 成立,并不是隔离的进程 // 根据进程名称和用户 ID 得到应用程序进程,由于不存在,则为 null 。 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); checkTime(startTime, "startProcess: after getProcessRecord"); // 省略部分代码 } else { // If this is an isolated process, it can't re-use an existing process. app = null; } // 当进程已经被分配的 PID 时, if (app != null && app.pid > 0) { } // 应用程序进程不存在,创建新的进程 if (app == null) { checkTime(startTime, "startProcess: creating new process record"); // 创建应用程序进程 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); if (app == null) { } app.crashHandler = crashHandler; checkTime(startTime, "startProcess: done creating new process record"); } else { // If this is a new package in the process, add the package to the list app.addPackage(info.packageName, info.versionCode, mProcessStats); checkTime(startTime, "startProcess: added package to existing proc"); } // 创建应用程序进程后,最终调用 startProcessLocked 方法 startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);}

地点的startProcessLocked方法最后调用了下边这些startProcess洛克d。

 private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { // ................ 省略 checkTime(startTime, "startProcess: starting to update cpu stats"); updateCpuStats(); checkTime(startTime, "startProcess: done updating cpu stats"); try { // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkTime(startTime, "startProcess: asking zygote to start proc"); 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!"); checkTime(startTime, "startProcess: done updating pids map"); } catch (RuntimeException e) { } }

能够看看地点调用了Process.start方法运转三个进程。在那之中有这样一小段代码,如下:

if (entryPoint == null) { entryPoint = "android.app.ActivityThread";}Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName,....);

Process.start(卡塔尔方法的率先个参数是 entryPoint
指明入口类是ActivityThread(固然如此名字是XXThread,但事实上是个普通类卡塔尔国,而Java的进口一般都以main方法,那么ActivityThread
的 main 方法将要那地运行。

ActivityThread.main方法并不复杂,来看下它大意干些什么。

 public final class ActivityThread { final Looper mLooper = Looper.myLooper(); final H mH = new H(); final ApplicationThread mAppThread = new ApplicationThread(); private static volatile ActivityThread sCurrentActivityThread; Instrumentation mInstrumentation; static volatile Handler sMainThreadHandler; public static void main(String[] args) { // 初始化主线程的消息队列 Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach; if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // 开启消息循环 Looper.loop(); } private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if  { // 是否为系统进程 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId; RuntimeInit.setApplicationObject(mAppThread.asBinder; final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } } else { // 省略系统进程代码 } // 省略 ViewRootImpl 相关代码 }}

 // AMS的 attachApplication方法 public final void attachApplication(IApplicationThread thread) { synchronized  { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity; } }
  1. Looper.prepareMainLooper(卡塔尔(قطر‎;希图循环主线程。
  2. 创设一个 ActivityThread 对象并attach(卡塔尔;最后sCurrentActivityThread =
    this; //
    当前静态sCurrentActivityThreadAMS.attachApplication(mAppThread);//
    mAppThread是ApplicationThread
  3. 调用Looper.loop();使主线程中国国投息循环

AMS.attachApplication(mAppThread卡塔尔国;中又调用了AMS的attachApplication洛克d,查看该方法:

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ProcessRecord app; // 移除超时消息,应用程序在规定时间内完成了启动。 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); try{ // 序号1. ************************** IPC 调用 ActivityThread,绑定并创建Application ************************** thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked; }catch(Exception e){ // } boolean badApp = false; boolean didSomething = false; // See if the top visible activity is waiting to run in this process... // 序号2. ************************** 调度 Activity ************************** if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked { didSomething = true; } } catch (Exception e) { badApp = true; } } // Find any services that should be running in this process... // 序号3 ************************** 调度 Service ************************** if  { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } } // Check if a next-broadcast receiver is in this process... // 序号4 ************************** 调度 Broadcast ************************** if (!badApp && isPendingBroadcastProcessLocked { try { didSomething |= sendPendingBroadcastsLocked; } catch (Exception e) { // If the app died trying to launch the receiver we declare it 'bad' badApp = true; } }}

以此地点代码超级多,须要特别注意:上面把那多少个步骤分为多少个序号:

  1. thread.bindApplication启动Application
  2. 启动Activity
  3. 启动Service
  4. 启动Broadcast

各种序号里面都实施跳转多次,三个序号二个序号来说,不然轻松犯迷糊。AMS.attachApplication(mAppThread)
序号一

先看 thread.bindApplication,这是三个IPC通讯,thread是IApplicationThread
接口,最终调用的措施是服务端真正的Binder对象即
ApplicationThread.bindApplication()

 public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) { // delete the fucking code ................... sendMessage(H.BIND_APPLICATION, data);}

可以见到该方法发送一条H.BIND_应用程式LICATION新闻交给handler管理。大家看下那些Handler,在ActivityThread的个中。

public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString); switch  { case LAUNCH_ACTIVITY: { final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); } break; case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication; break; case RELAUNCH_ACTIVITY: { ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity; } break; case PAUSE_ACTIVITY: { SomeArgs args =  msg.obj; handlePauseActivity args.arg1, false, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); maybeSnapshot(); } break; case PAUSE_ACTIVITY_FINISHING: { SomeArgs args =  msg.obj; handlePauseActivity args.arg1, true, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); } break; // .................. delete }

基于音讯case
BIND_APPLICATION:将执行ActivityThread.handleBindApplication;方法。

private void handleBindApplication(AppBindData data) { // 设置进程名 Process.setArgV0(data.processName); // 创建 Android 运行环境 ContextImpl . final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); // 初始化 Intrumentation 对象 if (data.instrumentationName != null) { try { java.lang.ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName.newInstance(); } catch (Exception e) { } mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection); } else { mInstrumentation = new Instrumentation(); } try { // If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. // 创建 Application 对象 Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; // don't bring up providers in restricted mode; they may depend on the // app's custom Application class if (!data.restrictedBackupMode) { List<ProviderInfo> providers = data.providers; if (providers != null) { installContentProviders(app, providers); // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } } // Do this after providers, since instrumentation tests generally start their // test thread at this point, and we don't want that racing. try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { } try { // 执行 Application 的 onCreate 方法 mInstrumentation.callApplicationOnCreate; } catch (Exception e) { } } finally { }}

AMS.attachApplication(mAppThread)
序号二
序号二调用了mStackSupervisor(ActivityStackSupervisorState of Qatar.attachApplicationLocked方法:

 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get; if (!isFocusedStack { continue; } ActivityRecord hr = stack.topRunningActivityLocked(); if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + hr.intent.getComponent().flattenToShortString; throw e; } } } } } if (!didSomething) { ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); } return didSomething; }

该办法遍历 ActivityStack 和 TaskRecord,找到坐落于 Activity 仓库顶上部分的二个ActivityRecord 对象 hr,接着检查这一个 Activity 组件的客商 ID 和
进度名是还是不是与 ProcessRecord 对象 app 所陈诉的应用程序的客户 ID
和进度名肖似,假若相通,则调用
StackSupervisor.realStartActivityLocked方法来号令该应用程序进度运行三个Activity 组件。

 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { // .... 删 删 删 删 删 删 删 删 fuck app.thread.scheduleLaunchActivity(new Intent, r.appToken, System.identityHashCode, r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); }

StackSupervisor.realStartActivityLocked方法内部调用了app.thread.scheduleLaunchActivity(卡塔尔方法,在那之中thread是ApplicationThread类型,binder对象。

ApplicationThread.scheduleLaunchActivity方法如下:

@Overridepublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); // .......... delete code sendMessage(H.LAUNCH_ACTIVITY, r);}

scheduleLaunchActivity里面相同是发送了一条handler音信。总部方handleMessage管理的新闻类型,将实施ActivityThread.handleLaunchActivity(卡塔尔方法。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // Initialize before creating the activity WindowManagerGlobal.initialize(); Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); } else { // If there was an error, for any reason, tell the activity // manager to stop us. try { ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null, false); } catch (RemoteException ex) { // Ignore } }}

各自调用:

  1. performLaunchActivity将 Activity 组件运维起来
  2. handleResumeActivity方法将 Activity 组件的情事设置为 Resumed。

上边只讲Activity a = performLaunchActivity(r, customIntent);就能够了,handleResumeActivity设置Resumed就从不什么样要求说了。

ActivityThread.performLaunchActivity是个广大重要的法子
,大家最后面提到某个 首重要角色色对象 的安装都以在这里个法子里面伊始化的。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // 获取ActivityInfo信息 ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } // 获取要启动的Activity的组件信息 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 activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass; r.intent.setExtrasClassLoader; r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader; } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString; } } try { // 这个地方我稍有疑惑,因为根据前面的逻辑 BIND_APPLICATION消息[app == null情况下]->handleApplication()中 // 已经使用LoadedApk.makeApplication()生成一个Application对象了,这里在case LAUNCHER_ACTIVITY又调用一遍。 // 不过LoadedApk.makeApplication有判断null处理,所以只会返回一个Application对象啦! Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { // 创建 Activity的 ContextImpl ,作为 Activity 的运行上下文环境 Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager; // 构造Configuration对象 Configuration config = new Configuration(mCompatConfiguration); if (r.overrideConfig != null) { config.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); // ============= Window对象 Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } // ******** 重要 : activity.attach(),我最前面提到的这个方法,把上面这些重要对象都设置为activity的成员变量。******** activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window); if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; activity.mStartedActivity = false; // 设置主题 int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme; } activity.mCalled = false; if (r.isPersistable { // 根据是否需要持久化调用此方法通知Activity已被创建和启动 // 回调 Activity 的 onCreate 函数 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { 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 的 onStart 函数 activity.performStart(); r.stopped = false; } if (!r.activity.mFinished) { if (r.isPersistable { // Activity 的 onRestoreInstanceState 函数 if (r.state != null || r.persistentState != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState); } } else if (r.state != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } } if (!r.activity.mFinished) { activity.mCalled = false; if (r.isPersistable { mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState); } else { 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; } } // 返回创建并初始化过的activity对象 return activity;}

到底说完了序号1和序号2,这里的序号1和序号2指的是下图那多少个步骤的前2个:

图片 5AMS.attachApplication中方法的前2个

讲了这么多,AMS.attachApplication那么些艺术还未实践完,小编了个去,累死了!写的最累的一篇博客了。时序图实在懒得画了,画那一个图预计也够呛,这篇作品篇幅即使和别的剖析AMS的稿子比起来到底短些了,因为好多篇章差没多少把源码全部都贴上了,笔者瞧着都晕,单单AMS.startActivityAsUser->ActivityStackSupervisor.realStartActivityLocked
那9步就够你贴上十几页了,那部分当真跳来跳去搞得人扑朔迷离,并且每段代码都以千百行,不过最根本实乃终极这两步,所以自身把我省略的跳转代码都省掉了,倘使具体研商某些步骤就相比较便于了,风野趣的能够搜寻9步中的某一段代码举办具体深入分析。花了100%3天时间,如若你欢畅,请点二个赞!nnd……Fuck
the code!!!

小结从上边的推行流程:我们开采Application会成立叁个appContext,多少个Activity会创建多个Context,(二个Service也会成立三个Context卡塔尔国,那么一个使用中
Context的总数 = Activity对象数 + Service对象数 + 1个Application对象。四大组件中的布RhodescastReciver和ContentProvider的Context都以一贯或间接来自于
Application,Activity,Service。

末段找来自个儿参考过的一种博主画的图,和本人的流水生产线大概,盗图一张!

图片 6image.png

连锁补偿表明ActivityStack :Android 中的 Activity
组件酒店新闻,也等于Task。ActivityStackSupervisor:管理ActivityStack的类。

参考Android开辟格局查究Android源码设计情势Android 7.0
源码Activity运转进程深入分析(从Launcher运维State of QatarAndroid 6.0 Launcher 运转Activity 进程源码分析

发表评论

电子邮件地址不会被公开。 必填项已用*标注