Android Service源码浅析

Service是什么

官方定义:

在Android里面,服务有两种存在的形式

1、依托于其他组件存在,例如:AIDL
这种服务在启动的时候会调用bindService()将指定的Context绑定到Service中(一个service允许绑定多个组件)
一旦Service中绑定的组件被清空,该服务就会被停止

2、独立存在,自己悄悄咪咪做一些事情的
这类服务启动的时候调用startService()启动,并调用stopSelf()或者stopService()停止服务

Service生命周期

直接上官方的一张图:

Tips

• 无论是那种方式结束Service, onDestory()都会被回调;

同样,无论以哪种方式启动service,onCreate()都会回调

• Service只要没有指定运行的process都是运行在主线程

• 通过startService启动的服务依然可以调用bindService绑定组件

Service如何创建

从上面生命周期以及Service简介中,我们知道启动服务有两种方式

1、bindService()

2、startService()

下面会从源码(API 28)来分析这两种方式的差异

bindService() 方法调用链

startService() 方法调用链

可以看出最终start或者bind的任务都是交到AMS中的ActiveServices执行的,

bindService到底和startService到底有什么区别呢?


先看startService的核心代码: ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, String callingPackage, int userId)
        throws TransactionTooLargeException {
    if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
            + " type=" + resolvedType + " args=" + service.getExtras());

    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        if (callerApp == null) {
            throw new SecurityException(
                    "Unable to find app for caller " + caller
                    + " (pid=" + Binder.getCallingPid()
                    + ") when starting service " + service);
        }
        callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }

    //创建ServiceRecord
    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType, callingPackage,
                callingPid, callingUid, userId, true, callerFg);
    if (res == null) {
        return null;
    }
    if (res.record == null) {
        return new ComponentName("!", res.permission != null
                ? res.permission : "private to package");
    }

    ServiceRecord r = res.record;
    //执行启动前的检查

    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    ProcessStats.ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
    }
    r.callStart = false;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked();
    }
    //调用bringUpServiceLocked拉起对应service
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
   //...
    return r.name;
}

概括起来分为3步:

  1. 为启动的Service创建ServiceRecord
  2. 执行启动前的一系列检查
  3. 含有BIND_AUTO_CREATE标记,调用bringUpServiceLocked()执行最终的拉起操作

bindService()核心代码 ActiveServices.java
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags,
        String callingPackage, int userId) throws TransactionTooLargeException {
    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
            + " type=" + resolvedType + " conn=" + connection.asBinder()
            + " flags=0x" + Integer.toHexString(flags));
    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
    if (callerApp == null) {
        throw new SecurityException(
                "Unable to find app for caller " + caller
                + " (pid=" + Binder.getCallingPid()
                + ") when binding service " + service);
    }
    //根据传入的token,从ActivityStack中获取对应的ActivityRecord
    ActivityRecord activity = null;
    if (token != null) {
        activity = ActivityRecord.isInStackLocked(token);
        if (activity == null) {
            Slog.w(TAG, "Binding with unknown activity: " + token);
            return 0;
        }
    }

    final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
    //创建对应的ServiceRecord
    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType, callingPackage,
                Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
    if (res == null) {
        return 0;
    }
    if (res.record == null) {
        return -1;
    }
    ServiceRecord s = res.record;

    final long origId = Binder.clearCallingIdentity();

    try {


        mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
                s.appInfo.uid, s.name, s.processName);
        //建立ConnectionRecord
        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        ConnectionRecord c = new ConnectionRecord(b, activity,
                connection, flags, clientLabel, clientIntent);

        IBinder binder = connection.asBinder();
        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            s.connections.put(binder, clist);
        }
        clist.add(c);
        b.connections.add(c);
        //添加ConnectionRecord到Activity.connections中
        //Activity会在被ActivityStack移除的时候调用ActiveServices.removeConnectionLocked
        //清理相关Connection并完成生命周期的同步
        if (activity != null) {
            if (activity.connections == null) {
                activity.connections = new HashSet<ConnectionRecord>();
            }
            activity.connections.add(c);
        }
        b.client.connections.add(c);
        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
            b.client.hasAboveClient = true;
        }
        if (s.app != null) {
            updateServiceClientActivitiesLocked(s.app, c, true);
        }
        //添加传入的Connection到ActiveServices中
        clist = mServiceConnections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            mServiceConnections.put(binder, clist);
        }
        clist.add(c);

        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
                return 0;
            }
        }

    } finally {
        Binder.restoreCallingIdentity(origId);
    }

    return 1;
}

概括起来可以分为以下4个步骤:

  1. 获取需要bind的Activity对应的ActivityRecord
  2. 创建对应的ServiceRecrod
  3. 创建对应的ConnectionRecord,并添加到ActivityRecord.connections中,会在Activity被ActivityStack移除的时候调用ActiveServices.removeConnectionLocked清理相关Connection并完成生命周期的同步
  4. 含有BIND_AUTO_CREATE标记,调用bringUpServiceLocked()执行最终的拉起操作

bindService和startService两种方式小结:

生命周期的区别:

  1. bindService会有bind以及unBind的回调,没有onStartCommand回调,监听是否绑定是通过IServiceConnection完成的
  2. startService会有onStartCommand回调,没有绑定相关回调

源码启动时候的区别:

  1. startService就只会有创建ServiceRecord的逻辑,没有其他特殊逻辑
  2. bindService因为需要bind到对应Activity,所以多一个建立连接(ConnectionRecord)并和ActivityRecord建立关系的逻辑

如何设置为前台服务

调用函数Service.startForeground(int id, Notification notification)就可以将Service设置为前台服务。

调用setFpreground之后的方法调用链如下:

final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
        boolean oomAdj) {
    if (isForeground != proc.foregroundServices) {
        proc.foregroundServices = isForeground;
        ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
                proc.info.uid);
        if (isForeground) {
            if (curProcs == null) {
                curProcs = new ArrayList<ProcessRecord>();
                mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
            }
            if (!curProcs.contains(proc)) {
                curProcs.add(proc);
                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
                        proc.info.packageName, proc.info.uid);
            }
        } else {
            if (curProcs != null) {
                if (curProcs.remove(proc)) {
                    mBatteryStatsService.noteEvent(
                            BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
                            proc.info.packageName, proc.info.uid);
                    if (curProcs.size() <= 0) {
                        mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
                    }
                }
            }
        }
        //更新进程优先级
        if (oomAdj) {
            updateOomAdjLocked();
        }
    }
}

进程优先级

Handler常见面试问题

从源码解释Handler常见面试问题

Tip:问题均从网上收集,参照了部分解答,在此谢过。

Q1:消息机制Hander是什么?有什么作用?有哪些要素?流程是怎样的?

1、Handler是什么?

是Android中一套在应用内使用的消息机制。

2、有什么作用

通过该机制,我们得以方便的发送消息以及收消息,我们常见的UI更新机制也是基于Handler运行。

3、有哪些要素

Handler的核心有这“三大件”:

Handler:提供给使用者的入口(发送、收消息)

MessageQueue:消息(Message)的队列,存储消息顺序

Looper:消息分发的驱动器,loop()一直在轮询(while(true))是否有消息,并分发消息

4、流程是怎么样的?

使用知乎大佬的图解释一下:

其他元素的职责在上面介绍过,这里说下Message的分类大概有哪些:

Message:消息,分为硬件产生的消息(如:按键、触摸、绘制等)和软件产生的消息

事实上,在整个消息循环的流程中,并不只有Java层参与,很多重要的工作都是在C++层来完成的。我们来看下这些类的调用关系。(copy from :https://zhuanlan.zhihu.com/p/38373877)

注:虚线表示关联关系,实线表示调用关系。

在这些类中MessageQueue是Java层与C++层维系的桥梁,MessageQueue与Looper相关功能都通过MessageQueue的Native方法来完成,而其他虚线连接的类只有关联关系,并没有直接调用的关系,它们发生关联的桥梁是MessageQueue。

Q2:为什么系统不建议在子线程访问UI?

避免多线程更新造成的一系列问题。

Q3:一个Thread可以有几个Looper?几个Handler?

1、一个Thread只有一个Looper,这个是通过ThreadLocal来保证的。

2、可以有多个Hander,Handler和Looper的关系是多对一的。

Q4:如何将一个Thread线程变成Looper线程?Looper线程有哪些特点?

调用Loop.prepareMainLooper,使线程的Looper变成主线程。

调用Looper.prepare(),就可以为当前线程创建一个Looper副本。

Q5:可以在子线程直接new一个Handler吗?那该怎么做?

不可以的,因为在子线程,所以这个Handler一定需要指定由哪个Looper分发消息;

所以在创建之前一定需要调用Looper.prepare()方法。

主线程在ActivityThread已经调用了,创建了mainLooper。

Q6:Message可以如何创建?哪种效果更好,为什么?

Message创建的时候android官方提倡使用Handler.obtainMessage()。

因为Message中保存了一个静态的Message对象链表,使用享元模式,减少了消息内存的占用

从复用的链表中获取一个对象,如果没有就创建。

public static Message obtain() {
    synchronized (sPoolSync) {
        if (sPool != null) {
            Message m = sPool;
            sPool = m.next;
            m.next = null;
            m.flags = 0; // clear in-use flag
            sPoolSize--;
            return m;
        }
    }
    return new Message();
}

什么时候加入到对象链表中呢?

public void recycle() {
    if (isInUse()) {
        if (gCheckRecycle) {
            throw new IllegalStateException("This message cannot be recycled because it "
                    + "is still in use.");
        }
        return;
    }
    recycleUnchecked();
}

消息使用完成调用recycle就可以回收该对象。

Q7:这里的ThreadLocal有什么作用?

ThreadLocal为每个线程保存了一个Looper副本。

ThreadLocal可以看这里:https://www.cnblogs.com/jasongj/p/8079718.html

Q8:主线程中Looper的轮询死循环为何没有阻塞主线程?

主线程中的Looper是保证应用一直运行的关键,我们常说的ANR实际上是占用主线程时间过长。

ActivityThread中初始化MainLooper

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    SamplingProfilerIntegration.start();
    //...
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();//mainLooper一直循环,保证应用进程一直存活

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

Q9:使用Hanlder的postDealy()后消息队列会发生什么变化?

调用了postDealy之后,MessageQueue会设置Message.when(保存消息应该什么时候执行)的值,

通过该值,MessageQueue会该消息插入到自己保存的消息队列(链表实现)中。

boolean enqueueMessage(Message msg, long when) {
    if (msg.target == null) {
        throw new IllegalArgumentException("Message must have a target.");
    }
    if (msg.isInUse()) {
        throw new IllegalStateException(msg + " This message is already in use.");
    }

    synchronized (this) {
        if (mQuitting) {
            IllegalStateException e = new IllegalStateException(
                    msg.target + " sending message to a Handler on a dead thread");
            Log.w(TAG, e.getMessage(), e);
            msg.recycle();
            return false;
        }

        msg.markInUse();
        msg.when = when;//设置应该什么时候执行
        Message p = mMessages;
        boolean needWake;
        if (p == null || when == 0 || when < p.when) {
            // New head, wake up the event queue if blocked.
            msg.next = p;
            mMessages = msg;
            needWake = mBlocked;
        } else {
            // Inserted within the middle of the queue.  Usually we don't have to wake
            // up the event queue unless there is a barrier at the head of the queue
            // and the message is the earliest asynchronous message in the queue.
            needWake = mBlocked && p.target == null && msg.isAsynchronous();
            Message prev;
            //在链表中插入当前消息,根据执行的时间
            for (;;) {
                prev = p;
                p = p.next;
                if (p == null || when < p.when) {
                    break;
                }
                if (needWake && p.isAsynchronous()) {
                    needWake = false;
                }
            }
            msg.next = p; // invariant: p == prev.next
            prev.next = msg;
        }

        // We can assume mPtr != 0 because mQuitting is false.
        if (needWake) {
            nativeWake(mPtr);
        }
    }
    return true;
}

Q10:如何解决Handler导致的泄漏问题

Handler导致泄漏的根本原因是Handler创建的时候为应用的内部类,持有了外部类的引用,

这个时候遇到有消息执行比较久(如:网络请求等),就会导致已经退出Activity了但是其引用还被Handler持有。

解决方案有两个建议:

1、实例化Handler的时候尽量创建一个静态内部类

2、保存外部Context的引用的时候使用弱引用

Activity启动流程

Activity 启动流程

主要分为如下两个方面介绍:

1、Activity启动基本流程

2、Activity任务栈

Activity启动基本流程

从Context发出startActivity指令到页面可见大抵会经过如下类:

Instrumentation:对外提供管理Activity接口

ActivityManagerService(AMS):系统服务,管理应用的Activity、Process、Service等

ActivityStackSupervisor:管理ActivityStack

ActivityStack:Activity任务栈

ActivityThread:应用进程

First Part 启动前的准备工作

startActivity有多个重载函数,最终都会调用这个重载函数

public void startActivityForResult(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());
        }

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

无论是否有父级Activity最后都会调用到 Instrumentation.execStartActivity这个函数,该函数通过AIDL与AMS通信,并正式进入Activity启动流程。

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);
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        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;
}

ActivityManagerService并不直接负责拉起Activity(毕竟是一个系统级的老大),它提供了调用其他服务的入口,并转发相关请求。

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
            false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

一个Activity要启动需要知道,启动之后位于哪个栈(Activity启动模式、Activity任务栈)。所以在真正拉起Activity之前,ActivityStackSupervisor会进行如下流程:

1、对AMS加同步锁,通过PMS收集目标Activity的基本信息(startActivityMayWait)
2、初步检查Activity是否可以启动,如果不可以返回相关错误(startActivityLocked)
3、确定在哪个栈(启动的时候携带的Flag,例如NEW_TASK会在这里判断并得出最终
目标Activity所在的栈),分发到相应栈开启Activity(startActivityUncheckedLocked)

在确定Activity可以启动且查找到应该在的任务栈之后,ActivityStack会通过启动传入的标志位(如NEW_TASK等)调整ActivityRecord在TaskRecord中的位置。

最终会调用到ActivityStack的resumeTopActivityInnerLocked:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    final ActivityRecord next = topRunningActivityLocked(null);

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

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        //ActivityRecord在创建的时候并不会指定其所在的进程(ProcessRecord),
        //只有在第一次开启了对应的activity之后才会指定所在进程;
        //所以这也是如何判断Activity是否直接resume的标志
        updateLRUListLocked(next);
        mService.updateOomAdjLocked();

        try {
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                    mService.isNextTransitionForward(), resumeAnimOptions);
            mStackSupervisor.checkReadyForSleepLocked();

            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
        } catch (Exception e) {

            return true;
        }

        // From this point on, if something goes wrong there is no way
        // to recover the activity.
        try {
            next.visible = true;
            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;
        }
        next.stopped = false;

    } else {

        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    //没有进程记录(即宿主APP的ProcessRecord),执行start流程
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    return true;
}

该函数通过Activity是否包含宿主App的ProcessCord来判断是resume还是start。

Second Part 开始启动

从第一部分末尾我们可以知道,所有Activity最终的启动发起是交给ActivityStackSupervisor.startSpecificActivityLocked来完成的。

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    //检查activity所在的应用是否有进程记录
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);
    //如果有记录,说明已经拉起过,执行启动Activity流程
    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(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }
    //没有进程记录,应该先拉起对应的Application
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

来到最后一个函数realStartActivityLocked(从名字也可以看出是最后的流程):

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
    //...
    mService.updateLruProcessLocked(app, true, null);
    mService.updateOomAdjLocked();

    final TaskRecord task = r.task;
    if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
            task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
        setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
    }

    final ActivityStack stack = task.stack;
    try {
        if (app.thread == null) {
            throw new RemoteException();
        }
        //...
        app.forceProcessStateUpTo(mService.mTopProcessState);
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
        //...
    } catch (RemoteException e) {
        if (r.launchFailed) {
            // This is the second time we failed -- finish activity
            // and give up.
            Slog.e(TAG, "Second failure launching "
                  + r.intent.getComponent().flattenToShortString()
                  + ", giving up", e);
            mService.appDiedLocked(app);
            stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                    "2nd-crash", false);
            return false;
        }

        // This is the first time we failed -- restart process and
        // retry.
        app.activities.remove(r);
        throw e;
    }
    //...

    return true;
}

可以看出,每次启动Activity,都会触发AMS更新进程优先级以及Lru记录。

最终启动工作是交由Application的主进程ActivityThread.handleLaunchActivity来完成的(实际上是先通过AIDL发送到ApplicationThread,再转发到ActivityThread的)。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    //...
    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);

        //...
            r.paused = true;
        }
    } 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
        }
    }
}

该函数主要执行两个流程:

performLaunchActivity();

1、使用ClassLoader加载并创建对应的Activity
2、通过ActivityClientRecord中的LoadApk创建Application(makeApplication函数 —–> 如果创建了那么直接返回;如果没有,创建AppContext以及Application)
3、创建Activity的baseContext
4、执行Activity.attatch 真正的Activity参数初始化方法
5、Instrumentation通知Activity.onCreate
6、Activity执行performStart完成部分初始化,同样由Instrumentation通知Activity.onStart

handleResumeActivity();

至此,Activity启动基本完成。

启动入口Activity有哪些区别?

在Activity启动的第二部分开始,我们知道ActivityStackSupervisor.startSpecificActivityLocked中会通过AMS中是否存在进程记录来判断应用是否启动,如果没有启动,那么调用AMS.startProcessLocked先fork出对应进程

注意:实际上调用了多个重载函数,代码有精简
private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    long startTime = SystemClock.elapsedRealtime();
    checkTime(startTime, "startProcess: starting to update cpu stats");
    updateCpuStats();
    checkTime(startTime, "startProcess: done updating cpu stats");
    try {
        int uid = app.uid;
        int[] gids = null;
        int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
        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);
    } catch (RuntimeException e) {
    }
}

Process大概流程如下图:

主要是通过Socket进行进程通信传递消息到ZygoteInit,然后由Zygote fork出进程。

而后会通过反射调用到ActivityThread.main()创建新的应用主进程,其中ActivityThread.attatch()会调用到AMS.attachApplicationLocked进而创建对应进程的ProcessRecord,创建之后会检查是否有Activity需要拉起,从而,拉起根Activity。

Window何时创建?

在ActivityThread.performLaunchActivity()中有一个步骤是调用

Activity.attatch()初始化Activity的Context以及其他参数,这里就包含对PhoneWindow的创建并加入到WindowManagerService。

DecorView何时创建,并开始第一次绘制?

在ActivityThread.handleResumeActivity()中,

执行performResumeActivity之后,会从window中获取到DecorView,然后将decor加入到WindowManagerService中(WindowManagerService.addView —> WindowManagerGlobal.addView);

WindowManagerGlobal.addView:

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {
    //...
    ViewRootImpl root;
    View panelParentView = null;
    //...
    synchronized (mLock) {
        // Start watching for system property changes.
        if (mSystemPropertyUpdater == null) {
            mSystemPropertyUpdater = new Runnable() {
                @Override public void run() {
                    synchronized (mLock) {
                        for (int i = mRoots.size() - 1; i >= 0; --i) {
                            mRoots.get(i).loadSystemProperties();
                        }
                    }
                }
            };
            SystemProperties.addChangeCallback(mSystemPropertyUpdater);
        }
        //...
        //创建绘制的时候根View
        root = new ViewRootImpl(view.getContext(), display);

        view.setLayoutParams(wparams);

        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
    }

    // do this last because it fires off messages to start doing things
    try {
        //调用setView,触发第一次绘制并开始接收垂直同步消息
        root.setView(view, wparams, panelParentView);
    } catch (RuntimeException e) {
        // BadTokenException or InvalidDisplayException, clean up.
        synchronized (mLock) {
            final int index = findViewLocked(view, false);
            if (index >= 0) {
                removeViewLocked(index, true);
            }
        }
        throw e;
    }
}

所以,所有元素开始可见是在Activity.onResume之后

Activity任务栈

管理ActivityRecord的终极老大是ActivityStackSupervisor,它包含两个基本的ActivityStack.

实际上Android 4.4以前只有一个mHistory 来管理所有的 activity;在后期,芯片厂商为了增加新feature有可能在这里新增一个或者多个栈,比如Multi-window的实现,所以才新增了ActivityStackSupervisor并变更为新的栈管理架构。

其他的基本对应关系如下:

Activity ————————- ActivityRecord

一个任务栈 ————————- TaskRecord

img