Android 四大组件的工作过程

四大组件的运行状态

  • Activity:
    展示一个界面并和用户交互,它扮演的是一个前台界面的角色。

  • Service:
    计算型组件,用于后台执行一系列计算任务,运行在主线程,分为启动状态和绑定状态。

  • BroadcastReceiver:
    消息型组件,它工作在系统内部,不合适用来执行耗时操作,主要用于不同组件或不同应用之间的消息传递。

  • ContentProvider:
    数据共享型组件。

Actiivity 的工作过程

常见的 Activity 启动方法:

Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);

进入到 Activity 中的 startActivity 方法中,调用 startActivityForResult;

  @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

mParent 代表的是 ActivityGroup,是一个 Fragment,然后查看mInstrumentation.execStartActivity

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

进入到 Instrumentation 的execStartActivity中,Activity 的真正实现由ActivityManagerNative.getDefault().startActivity来完成的。checkStartActivityResult的作用是检查启动 Activity 的结果。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //检查启动结果
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
...
public static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

ActivityManagerNative 是一个Binder 类继承了 IActivityManager,gDefault是一个 IActivityManager 的 Binder 对象,它是一个单例的封装类,get 方法就是初始化。

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
...
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
...
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

startActivity 方法实际来源于 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;
...

ActivityManagerService(简称 AMS)是 ActivityManagerNative 的实现类,所直接看它的startActivity方法

public final class ActivityManagerService extends ActivityManagerNative
...
    @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());
    }

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

mActivityStarter.startActivityMayWait又将我们带入 ActivityStarter 中,源码很长,跟书中已经有些许不同,根据我下图的顺序可以正确的查看源码顺序。

Activity 在 ActivityStarter、ActivityStackSupervisor、ActivityStack中的传递顺序
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), 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);
...
    }

上面这段代码很重要, app.thread 的类型为 IApplicationThread

public interface IApplicationThread extends IInterface {

IApplicationThread 是一个 Binder 类型的接口。内部包含了大量启动、停止 Activity 的接口,此外还包含了启动和停止服务的接口。

public final class ActivityThread {
    private class ApplicationThread extends ApplicationThreadNative {
...

ApplicationThread 是 ActivityThread 中的内部类,它继承了 ApplicationThreadNative :

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {

ApplicationThreadNative 继承了 Binder 并实现了 IApplicationThread 。ApplicationThreadNative 是系统为 AIDL 文件自动生成的代码,它是一个抽象类,ApplicationThread 就成为了 IApplicationThread 的最终实现者。

         @Override
        public 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();

...

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

ApplicationThread 通过内部方法scheduleLaunchActivity发送一个启动 Activty 的消息交由 Handler 处理。

    final H mH = new H();
...
    private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
...
  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
...

Handler H 对 “LAUNCH_ACTIVITY” 进行处理:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

           ...
    }

performLaunchActivity方法最终完成了 Activity 对象的创建和启动过程,handleResumeActivity方法就是调用 Activity 的onResume 这一生命周期方法。

下面分析 performLaunchActivity

  1. 从 ActivityClientRecord 中获取待启动的 Activity 的组件信息
ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);
        }

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

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
        }
  1. 通过 Instrumentation 的 newAcitivity 方法使用类加载器创建 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(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
  1. 通过 LoadedApk 的makeApplication 方法来尝试创建 Application 对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException("Unable to instantiate application " + appClass + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                //调用 Application 的 OnCreate 方法。
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()+ ": " + e.toString(), e);
                }
            }
        }
...
        return app;
    }

从 makeApplication 的实现可以看出,如果 Application 已经被创建过了,就不会再重复创建。Application 对象是由 Instrumentation 来完成的,也是通过类加载器来来实现。之后系统会使用instrumentation.callApplicationOnCreate方法来调用 Application 的 OnCreate 方法。

  1. 创建 ContextImpl 对象并通过 Activty 的 attach 方法来完成一些重要数据的初始化
Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                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 = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                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);

ContextImpl 是一个很重要的数据结构,它是 Context 的具体实现,ContextImpl 通过 Activity 的 attch 方法来个 Activty 简历关联的,在 attch 方法中 Activty 还会完成 Window 的创建并简历自己和 Window 的关联。

  1. 调用 Activty 的 onCreate 方法
mInstrumentation.callActivityOnCreate(activity, r.state);

Service 的工作过程

两种工作状态;

  • 启动状态
        Intent intent = new Intent(this, MyService.class);
        startService(intent);
  • 绑定状态
        bindService(intent, conn, BIND_AUTO_CREATE);

Service 的启动过程

startService:

public class ContextWrapper extends Context {
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base;
    }
    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }

Activity 创建时通过 attach 方法将一个 ContextImpl 对象关联起来,mBase 就是这个对象。(设计模式:桥接模式),下面看 ContextImpl 的 starService 的实现。

    @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }
private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
           ...
    }

上述代码通过 ActivityManagerNative.getDefault().startService(AMS)来启动服务的行为是一个远程过程调用。

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
    ...
    }
startService

realStartServiceLocked方法中,通过 app.thread 的 scheduleCreateService 方法来创建 Service 对象并调用其 onCreate,接着通过 sendServiceArgsLocked方法来调用 Service 的其他方法,比如 onStartCommand,这两个过程均是进程间通信。

app.thread 对象是 IApplicaitionThread 类型,实际就是 ActivityThread 的内部类 ApplicationThread(分析 Activity 的时候介绍过);

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

上述过程和 Activity 相似,调用 sendMessage 通过 Handler H 来处理,

 public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
...
               case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
 private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            //1.创建 Service 的实例
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //2.通过 Service 的 attach 方法建立二者之间的关系
            service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault());
            service.onCreate();
            //3.调用 Service 的 onCreate 方法并将 Service 对象存储到 ActivityThread 中的一个列表中;
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name + ": " + e.toString(), e);
            }
        }
    }

handleCreateService 主要完成了如下几件事:

  • 首先通过类加载器创建 Service 的实例;
  • 然后创建 Application 对象并通过 Service 的 attach 方法建立二者之间的关系
  • 最后调用 Service 的 onCreate 方法并将 Service 对象存储到 ActivityThread 中的一个列表中;
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();

realStartServiceLocked方法中还会调用sendServiceArgsLocked方法,最终通过 Handler H调用handleServiceArgs方法,接着就会调用 onStartCommand

Service 的绑定过程

bindService:

public class ContextWrapper extends Context {
...
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }

跟startService 一样,mBase 是 Context,ContextImpl 是它的实现类,所以直接看 ContextImpl 的 bindServiceCommon

 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
      ...
                // AMS 处理
                int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
    }

LoadedApk 的bindServiceCommon

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                sd = map.get(c);
            }
            if (sd == null) {
                // 将 c, context, handler, flags 存入并初始化 ServiceDispatcher 对象
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (map == null) {
                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
           //mServices 是一个 ArrayMap,它存储了一个应用当前活动的 ServiceConnection 和 ServiceDispatcher 的映射关系。
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();
        }
    }

static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
...
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

        InnerConnection(LoadedApk.ServiceDispatcher sd) {
            mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
        }

        public void connected(ComponentName name, IBinder service) throws RemoteException {
            LoadedApk.ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
                sd.connected(name, service);
            }
        }
    }
  //mServices 是一个 ArrayMap,它存储了一个应用当前活动的 ServiceConnection 和 ServiceDispatcher 的映射关系。
  private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
        = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();

    ServiceDispatcher(ServiceConnection conn,
            Context context, Handler activityThread, int flags) {
        mIServiceConnection = new InnerConnection(this);
        mConnection = conn;
        mContext = context;
        mActivityThread = activityThread;
        mLocation = new ServiceConnectionLeaked(null);
        mLocation.fillInStackTrace();
        mFlags = flags;
    }
    // 获取 ServiceDispatcher.InnerConnection 对象
    IServiceConnection getIServiceConnection() {
        return mIServiceConnection;
    }

...

LoadedApk 的`getServiceDispatcher` 方法将客户端的 ServiceConnection 对象转化为 getServiceDispatcher.InnerConnection 对象。因为服务的绑定有可能是跨进程的,因此 ServiceConnection 对象必须借助于 BInder 才能让远程服务端回调自己的方法,而 ServiceDispatcher 的内部类 Innconnection 刚好充当这一角色。


mServices 是一个 ArrayMap,它存储了一个应用当前活动的 ServiceConnection 和 ServiceDispatcher 的映射关系。在 ServiceDispatcher 内部保存了 ServiceConnection 和 InnerConnection 对象。

接着返回`bindServiceCommon`方法后半段,`ActivityManagerNative.getDefault().bindService`调用 AMS 的 `bindService`方法:

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {

...
requestServiceBindingsLocked(r, execInFg);
...
}

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind) throws TransactionTooLargeException {

...
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// ActivityThread 中处理
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
...
}
return true;
}

ActivityThread 中的`scheduleBindService`方法
    public final void scheduleBindService(IBinder token, Intent intent,
            boolean rebind, int processState) {
        updateProcessState(processState, false);
        BindServiceData s = new BindServiceData();
        s.token = token;
        s.intent = intent;
        s.rebind = rebind;

        if (DEBUG_SERVICE)
            Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
                    + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
        sendMessage(H.BIND_SERVICE, s);
    }
Handler `H` 接收:
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case BIND_SERVICE:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                handleBindService((BindServiceData)msg.obj);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
            case UNBIND_SERVICE:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                handleUnbindService((BindServiceData)msg.obj);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
在 H 内部,接收到 BIND_SERVICE 这类消息时,会交给 ActivityThread 的`handleBindService`方法来处理
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (DEBUG_SERVICE)
        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) {
                    IBinder binder = s.onBind(data.intent);
                    // 发布服务
                    ActivityManagerNative.getDefault().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
                ensureJitEnabled();
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to bind to service " + s
                        + " with " + data.intent + ": " + e.toString(), e);
            }
        }
    }
}
`handleBindService`中首先会根据 Service 的 token 取出 Service 对象,然后调用 Service 的 onBind 方法,Service 的 onBInd 方法会返回一个 BInder 对象给客户端使用,此时 Service 已经处于绑定状态,但是 onBind 是 Service 的方法,还需要调用客户端的 ServiceConnection 中的 onServiceConnected 来通知客户端,这个过程由`ActivityManagerNative.getDefault()`(AMS)的`publishService`方法:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                + " " + intent + ": " + service);
        if (r != null) {
            Intent.FilterComparison filter
                    = new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true;
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                        if (!filter.equals(c.binding.intent.intent)) {
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Not publishing to: " + c);
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Published intent: " + intent);
                            continue;
                        }
                        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                        try {
                        //核心代码
                            c.conn.connected(r.name, service);
                        } catch (Exception e) {

....
}

`publishServiceLocked`核心代码只有一句话:`c.conn.connected(r.name, service);`,它调用了 LoadedApk 的
 ServiceDispatcher.InnerConnection 类型的`connected`方法,service 是 onBind 方法返回的 Binder 对象。

private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

        InnerConnection(LoadedApk.ServiceDispatcher sd) {
            mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
        }

        public void connected(ComponentName name, IBinder service) throws RemoteException {
            LoadedApk.ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
                sd.connected(name, service);
            }
        }
    }
然后调用 `sd.connected(name, service);`,mActivityThread 就是 ActivtyThread 中的 Handler  H,Runcconnection 就可以经由 H 的 post 方法运行在主线程中。
    public void connected(ComponentName name, IBinder service) {
        if (mActivityThread != null) { 
            // 运行在主线程,mActivityThread 就是 H 
            mActivityThread.post(new RunConnection(name, service, 0));
        } else {
            doConnected(name, service);
        }
    }
    private final class RunConnection implements Runnable {
        RunConnection(ComponentName name, IBinder service, int command) {
            mName = name;
            mService = service;
            mCommand = command;
        }
        // mCommand = 0 连接服务, mCommand = 1 销毁服务
        public void run() {
            if (mCommand == 0) {
                doConnected(mName, mService);
            } else if (mCommand == 1) {
                doDeath(mName, mService);
            }
        }

        final ComponentName mName;
        final IBinder mService;
        final int mCommand;
    }
在 doConnected 中调用 `onServiceDisconnected`方法,Service 的绑定就完成了。
    public void doConnected(ComponentName name, IBinder service) {
        ServiceDispatcher.ConnectionInfo old;
        ServiceDispatcher.ConnectionInfo info; 
            old = mActiveConnections.get(name);

....
//如果有旧服务,使其断开链接
if (old != null) {
mConnection.onServiceDisconnected(name);
}
// 有新服务就链接
if (service != null) {
mConnection.onServiceConnected(name, service);
}
}


## BroadcastReceiver 的工作过程

#### 广播的注册过程

动态注册:

registerReceiver(mReceiver, filter);

进入 ContextWrapper 的`registerReceiver`
@Override
public Intent registerReceiver(
    BroadcastReceiver receiver, IntentFilter filter) {
    return mBase.registerReceiver(receiver, filter);
}
mBase 是 Context 类型,Context 是抽象类,它的实现是 ContextImpl,接着进入到 ContextImpl 的`registerReceiver`方法会调用`registerReceiverInternal`方法:

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
        IntentFilter filter, String broadcastPermission,
        Handler scheduler, Context context) {
    IIntentReceiver rd = null;
    // receiver 就是传入的广播对象
    if (receiver != null) {
        if (mPackageInfo != null && context != null) {
            if (scheduler == null) { 
                // 如果没有传入指定的线程,就默认指定主线程
                scheduler = mMainThread.getHandler();
            }
            //转换为 Binder 对象,为了跨进程通信
            rd = mPackageInfo.getReceiverDispatcher(
                receiver, context, scheduler,
                mMainThread.getInstrumentation(), true);
        } else {
            if (scheduler == null) {
                scheduler = mMainThread.getHandler();
            }
            rd = new LoadedApk.ReceiverDispatcher(
                    receiver, context, scheduler, null, true).getIIntentReceiver();
        }
    }
    try {
        // AMS  的 registerReceiver 方法
        final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                mMainThread.getApplicationThread(), mBasePackageName,
                rd, filter, broadcastPermission, userId);
        if (intent != null) {
            intent.setExtrasClassLoader(getClassLoader());
            intent.prepareToEnterProcess();
        }
        return intent;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
现在进入 ActivityManagerService 中的`registerReceiver`方法:

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
enforceNotIsolatedCaller("registerReceiver");
....
mRegisteredReceivers.put(receiver.asBinder(), rl);

        BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                permission, callingUid, userId);
        rl.add(bf);
        if (!bf.debugCheck()) {
            Slog.w(TAG, "==> For Dynamic broadcast");
        }
        mReceiverResolver.addFilter(bf);

...
return sticky;
}
}

代码很长,关键点就上面这部分,最终会把远程的 InnerReceiver 对象以及 IntentFilter 对象存储起来,这样整个广播的注册过程就完成了。


####广播的发送和接收过程

发送一条广播:

sendBroadcast(intent);

进入 ContextWrapper 的`sendBroadcast`:
@Override
public void sendBroadcast(Intent intent) {
    mBase.sendBroadcast(intent);
}
进入 ContextImpl 的`sendBroadcast`方法:

@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

进入 AMS 的`broadcastIntent`方法,该方法又调用`broadcastIntentLocked`方法

final int broadcastIntentLocked(...) {
...
// By default broadcasts do not go to stopped apps.
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
...

在 Android 3.1 中,默认广播不会发送给已经停止的应用,因为系统给 Intent 默认添加了**FLAG_EXCLUDE_STOPPED_PACKAGES**标志。
- **FLAG_EXCLUDE_STOPPED_PACKAGES:**表示广播会发送给已经停止的应用 ;
- **FLAG_INCLUDE_STOPPED_PACKAGES:**表示广播不会发送给已经停止的应用;

两种标志共存时,已**FLAG_INCLUDE_STOPPED_PACKAGES** 为准。

在`broadcastIntentLocked`方法内部,会根据 intent-filter 查找出匹配的广播接受者并经过一系列的条件过滤,最终将满足条件的广播接受者添加到 BroadcastQueue 中,接着 BroadcastQueue 就会将广播发送给相应的广播接受者。
    if ((receivers != null && receivers.size() > 0)
            || resultTo != null) {
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                callerPackage, callingPid, callingUid, resolvedType,
                requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                resultData, resultExtras, ordered, sticky, false, userId);

        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
                + ": prev had " + queue.mOrderedBroadcasts.size());
        if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
                "Enqueueing broadcast " + r.intent.getAction());

        boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
        if (!replaced) {
            queue.enqueueOrderedBroadcastLocked(r);
            //发送广播
            queue.scheduleBroadcastsLocked();
        }
    }
接着看一下 BroadcastQueue  中广播的发送过程的实现:
public void scheduleBroadcastsLocked() {
    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
            + mQueueName + "]: current="
            + mBroadcastsScheduled);

    if (mBroadcastsScheduled) {
        return;
    }
    //发送了一条消息给 mHandle
    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
    mBroadcastsScheduled = true;
}
BroadcastQueue  的`scheduleBroadcastsLocked`只是发送了一条消息给 mHandle,mHandle 会调用`processNextBroadcast(true);`方法
final void processNextBroadcast(boolean fromMsg) {
    synchronized(mService) {
        BroadcastRecord r;
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();
            final int N = r.receivers.size();
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                    + mQueueName + "] " + r);
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                        "Delivering non-ordered on [" + mQueueName + "] to registered "
                        + target + ": " + r);
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
            }
            addBroadcastToHistoryLocked(r);
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
                    + mQueueName + "] " + r);
        }

...

无序广播存储在 mParallelBroadcasts 中,系统会遍历 mParallelBroadcasts 并将其中的广播发送给它们所有的接受者,具体发送过程通过`deliverToRegisteredReceiverLocked`来实现,它内部有一个方法`performReceiveLocked`

performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);

进入`performReceiveLocked`方法:
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
        Intent intent, int resultCode, String data, Bundle extras,
        boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
    if (app != null) {
        if (app.thread != null) {
            try {
                app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                        data, extras, ordered, sticky, sendingUser, app.repProcState);
            } catch (RemoteException ex) {
                // Failed to call into the process. It's either dying or wedged. Kill it gently.
                synchronized (mService) {
                    Slog.w(TAG, "Can't deliver broadcast to " + app.processName
                            + " (pid " + app.pid + "). Crashing it.");
                    app.scheduleCrash("can't deliver broadcast");
                }
                throw ex;
            }
        } else {
            throw new RemoteException("app.thread must not be null");
        }
    } else {
        receiver.performReceive(intent, resultCode, data, extras, ordered,
                sticky, sendingUser);
    }
}
`app.thread.scheduleRegisteredReceiver`方法对应的是 ActivityThread 的内部类 ApplicationThread 中的`scheduleRegisteredReceiver`方法:
    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
            int resultCode, String dataStr, Bundle extras, boolean ordered,
            boolean sticky, int sendingUser, int processState) throws RemoteException {
        updateProcessState(processState, false);
        receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                sticky, sendingUser);
    }
`receiver.performReceive`对应的是 LoadedApk 的 ReceiverDispatcher 的 InnerReceiver 中的`performReceive` 方法:

@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
+ " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
}
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}

在进入`performReceive`
    public void performReceive(Intent intent, int resultCode, String data,
            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
        final Args args = new Args(intent, resultCode, data, extras, ordered,
                sticky, sendingUser);

....
}

查看`Args`类
   final class Args extends BroadcastReceiver.PendingResult implements Runnable {
        private Intent mCurIntent;
        private final boolean mOrdered;
        private boolean mDispatched;

        public Args(...) {
            super(resultCode, resultData, resultExtras,
                    mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
                    sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
            mCurIntent = intent;
            mOrdered = ordered;
        }
        
        public void run() {
            ...
            receiver.onReceive(mContext, intent);

Args 实现了 Runnable 接口,里面 run 方法中执行了 BroadcastReceiver 的 onReceive 方法。也就是说应用到这里就能接收到广播了,同时 onReceive 方法是在广播接受者的主线程中被调用的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容