Android面试题-四大组件(68题)

Android面试题之四大组件+Fragment,包括Activity、Service、广播、ContentProvider和Fragment。

本文是我一点点归纳总结的干货,但是难免有疏忽和遗漏,希望不吝赐教。
转载请注明链接:https://blog.csdn.net/feather_wch/article/details/81136168

Android面试题-四大组件(73题)

版本:2018/8/3-1(2113)

1、四大组件的注册和调用方式

  1. Activity、Service、ContenProvider必须在AndroidManifest中注册
  2. BroadcastReceiver可以在AndroidManifest中注册,也可以代码中注册
  3. Activity、Service、ContenProvider的调用需要借助Intent
  4. BroadcastReceiver不需要借助Intent

Activity

2、Activity是什么?

  1. 一种展示型组件,用于展示界面,并且与用户进行交互。
  2. Activity的启动由Intent触发,Intent可分为隐式Intent和显式Intent
  3. 显式Intent需要明确指向一个Activity
  4. 隐式Intent可以指向一个或者多个Activity组件,也可能没有任何Activity处理该隐式Intent
  5. Activity具有特定的启动模式,也可以通过finish方法结束运行。

3、Activity启动流程中涉及的重要角色

  1. Instrumentation:监控应用与系统相关的交互行为。
  2. ActivityManagerService:组件管理的调度中心,基本上什么都不干,但是什么都管。
  3. ActivityStarterActivity启动的管理器。处理Intent和FlagActivity启动的影响。
  4. ActivityStackSupervisor:管理任务栈
  5. ActivityStack:管理任务栈中的Activity
  6. ActivityThread:主线程/UI线程,完成四大组件相关工作以及APP各种主要的任务。
    ActivityStackSupervisor是高版本才有的类,在系统支持多屏后,需要去管理多个ActivityStack

4、App的启动流程

  1. 图标点击:Lancher进程会通过Binder机制通知ActivityManagerService去进行ActivityC黄建等相关工作。
  2. AMS会让ActivityStarter(启动管理器)处理Intent和Flag,然后以Socket方式去通知Zygote进程
  3. Zygote进程会进行孵化(虚拟机和资源的复制—以加快启动速度), 然后fork出新进程。
  4. 新进程中会创建ActivityThread实例,在RuntimeInit.zygoteInit()中会调用invokeStaticMain,其内部会执行ActivityThred的main()方法
  5. ActivityThread中会创建Looper,开启消息循环
  6. 最后会进行Activity生命周期的回调-onCreate、onStart等方法

状态

5、Activity的状态

  1. 三种常驻状态多个中间态
  2. Resumed(运行状态):activity处于前台,用户可以进行交互。
  3. Paused(暂停状态): activity被部分遮挡,可见,不可交互。
  4. Stopped(停滞状态):activity不可见,不可交互。

6、Activity的通信方式有哪些?

  1. BroadcastReceiver和LocalBroadcastReceiver
  2. EventBus
  3. startActivityForResult

启动流程

7、Activity的启动方法

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

8、Activity的启动流程流程图和要点

graph TD;
    1(startActivity);
    2(startActivityForResult);
    3(mInstrumentation.execStartActivity);
    4(ActivityManager.getService.startActivity);
    5(checkStartActivityResult);
    6(realStartActivityLocked);
    7(app.thread.scheduleLaunchActivity);
    8(sendMessage-H.LAUNCH_ACTIVITY);
    9(handleMessage);
    10(handleLaunchActivity);
    11(WindowManagerGlobal.initialize);
    12(performLaunchActivity);
    13(handleResumeActivity);
    1-->2;
    2-->3;
    3-->4;
    3-->5;
    4-->6;
    6-->7;
    7-->8;
    8-->9;
    9-->10;
    10-->11;
    10-->12;
    10-->13;
graph TD;
    12(performLaunchActivity);
    14(getPackageInfo);
    15(mInstrumentation.<br/>newActivity);
    16(r.packageInfo.<br/>makeApplication);
    17(activity.attach);
    18(mInstrumentation.<br/>callActivityOnCreate);
    19(attachBaseContext);
    20(mUiThread/mApplication);
    21(new PhoneWindow);
    22(mWindow.<br/>setWindowManager);
    23(mWindow.<br/>setContainer);
    24(mWindow.<br/>getWindowManager);
    12-->14;
    12-->15;
    12-->16;
    12-->17;
    12-->18;
    17-->19;
    17-->20;
    17-->21;
    17-->22;
    17-->23;
    17-->24;
graph TD;
    13(handleResumeActivity);
    25(performResumeActivity);
    26(r.activity.getWindow);
    27(r.window.getDecorView);
    28(a.getWindowManager);
    29(wm.addView);
    13-->25;
    13-->26;
    13-->27;
    13-->28;
    13-->29;
  1. startActivity: 所有startActivity()方法最终会调用startActivityForResult()方法
  2. startActivityForResult: 内部执行mInstrumentation.execStartActivity.
  3. mInstrumentation.execStartActivity:Instrucmentation用于监控应用和系统的交互行为, 执行4、5两步的方法
  4. ActivityManager.getService.startActivity(): 获取到AMS并且执行startActivity()
  5. checkStartActivityResult():检查启动Activity的结果,没有成功启动就会抛出异常,例如Activity没有注册
  6. realStartActivityLocked:AMS执行startActivity会经过Activitystack后执行到ActivityStackSupervisor的该方法。会执行app.thread.scheduleLaunchActivity()
  7. app.thread.scheduleLaunchActivity: app.thread是IApplicationThread这个Binder类型接口, 发送消息H.LAUNCH_ACTIVITY给Handler H处理。
  8. sendMessage-H.LAUNCH_ACTIVITY: 发送消息给Handler
  9. handleMessage: 会执行handleLaunchActivity
  10. handleLaunchActivity: 启动工作,主要进行11、12、13三步的功能
  11. WindowManagerGlobal.initialize() : 初始化WM
  12. performLaunchActivity:会进行14、15、16、17、18五步的工作
  13. handleResumeActivity:主要进行25、26、27、28、29五步的功能
  14. getPackageInfo: 从ActivityClientRecord中获取到待启动的Activity的组件信息
  15. mInstrumentation.newActivity: 使用类加载器创建Activity对象
  16. r.packageInfo.makeApplication: 通过LoadedApk的方法创建Applicayiton对象,该对象唯一,不会重复创建。
  17. activity.attach: 调用该方法前会先创建ContexnImpl对象,然后调用该方法去完成Window的创建并且建立Activity和Window的关联。主要进行19、20、21、22、23、24 六步的工作
  18. mInstrumentation.callActivityOnCreate: 调用Activity的onCreate()
  19. attachBaseContext(context): 建立Context和Activity的联系:本质就是将ContextImpl实例作为成员变量保存在Activity内部。
  20. mUiThread/mApplication: 将UI线程和application保存到Activity内部(成员变量)
  21. new PhoneWindow(this): 创建Window(PhoneWindow), 并进行初始化工作
  22. mWindow.setWindowManager: 给Window设置WindowManager—通过context.getSystemService从WMS中获取
  23. mWindow.setContainer(mParent.getWindow()): 将当前Window所处的容器设置为父Activity的Window
  24. mWindowManager = mWindow.getWindowManager(): 将WM变量作为成员变量保存到Activity内部
  25. performResumeActivity: 通过Instrucmentation调用onStart和onResume
  26. r.activity.getWindow(): 获取到Window(在Activity的attach方法中创建了PhoneWindow)
  27. r.window.getDecorView(): 创建DecorView,设置为不可见INVISIBLE, 并且Activity内部保存了DecorView
  28. a.getWindowManager(): 获取到WindowManager
  29. wm.addView(decor, l): WM的addView方法将DecorView添加到Window中

performLaunchActivity

9、Activitiy启动流程中performLaunchActivity的作用?(5种)

  1. 从ActivityClientRecord中获取到待启动的Activity的组件信息
  2. 使用类加载器创建Activity对象
  3. 通过LoadedApk的方法创建Applicayiton对象,该对象唯一,不会重复创建。
  4. 会创建ContextImpl并且建立Context和Activity的联系,以及创建PhoneWindow,建立Window和Activity的联系。
  5. 调用Activity的onCreate()

activity.attach

10、Activitiy启动流程中activity.attach的作用?(6种)

  1. 建立Context与Activity的联系。
  2. 建立UIThread/Application与Activity的联系。
  3. 创建Window(PhoneWindow对象),建立与Activity的联系。
  4. Window设置父容器父Activity的window
  5. Window设置WindowManager
  6. 建立WindowManager与Activity的联系。

handleResumeActivity

11、Activity启动流程中handleResumeActivity的作用?(5种)

  1. 执行onStart()、onResume()—利用Instrucmentation
  2. 获取Window
  3. 创建DecorView、设置为不可见INVISIBLE、建立DecorView和Activity的联系。
  4. 获取Activity的WindowManager
  5. 调用WindowManager.addView(decorView, ...)将DecorView添加到WM中,完成显示的工作。

关系建立

12、如何创建Activity对象?

  1. ActivityThread.javaperformLaunchActivity()方法内,通过InstrucmentationnewActivity()方法,通过类加载器进行创建。

13、如何创建Application对象?

  1. ActivityThread.javaperformLaunchActivity()方法内,通过LoadedApkmakeApplication()方法创建Application对象。

14、如何建立Context/UIThread/Application/Window/WindowManager与Activity的联系?

  1. activity的attach方法中
  2. attach()ActivityThreadperformLaunchActivity中执行。

生命周期回调

15、onCreate在哪里被调用?

  1. performLaunchActivity通过Instrumentation调用

16、onStart、onCreate在哪里被调用?

  1. handleResumeActvity

startActivity源码

17、Activity的startActivity源码流程详解

//Activity.java
//1. 所有`startActivity()`方法最终会调用`startActivityForResult()`方法:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    //2. 父亲不为Null
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        //3. Instrumentation的execStartActivity去启动Activity
        Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(),//获取ApplicationThread
                        mToken, this,
                        intent, requestCode, options);
        ...
    } else {
        ...
    }
}

//Instrumentation.java
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
    ...省略...
    try {
        /**===============================================
         * 1.开启Activity
         *  1-获取到IActivityManager的Binder对象
         *  2-通过IPC让ActivityManagerService执行startActivity方法
         *===============================================*/
        int result = ActivityManager.getService() //Binder对象
                .startActivity(whoThread, ... ,options);
        /**===============================================
         *2. 检查启动Activity的结果
         * 没有成功启动就会抛出异常,例如Activity没有注册:
         *   Unable to find explicit activity class...have you declared this activity in your AndroidManifest.xml?"
         *===============================================*/
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

/**
 * ActivityManagerService处理startActivity流程:
 * startActivity() -> startActivityAsUser -> ...
 * -> ActivityStack的resumeTopActivityUncheckedLocked() -> ...
 * -> ActivityStackSupervisor的`realStartActivityLocked方法`
 */
//ActivityManagerService.java
public final int startActivity(IApplicationThread caller, ...,Bundle bOptions) {
    return startActivityAsUser(caller, ...,UserHandle.getCallingUserId());
}

//ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    //app.thread的类型为IApplicationThread
    /**============================================================
     * app.thread的类型为IApplicationThread(继承IInterface接口-Binder类型接口)
     * --内部包含大量Activity和Service启动/停止相关功能
     * --具体实现:ActivityThread(继承了ApplicationThreadNative)
     *    * ApplicationThreadNative继承Binder并且实现了IApplicationThread接口
     *      (ApplicationThreadNative和系统为AIDL文件生成的类的作用是一样的)
     *==============================================================*/
    app.thread.scheduleLaunchActivity(new Intent(r.intent), ... ,profilerInfo);
    ......
}

//ActivityThread.java的内部类:ApplicationThread
public final void scheduleLaunchActivity(Intent intent, IBinder token, ...,ProfilerInfo profilerInfo) {
    //1. 保存ActivityClientRecord需要的所有数据
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    ...
    r.overrideConfig = overrideConfig;
    //2. 发送消息给Handler H处理
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

//ActivityThread.java
private class H extends Handler {
    public static final int LAUNCH_ACTIVITY = 100;
    ......

    public void handleMessage(Message msg) {
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                //1. 交给`ActivityThread`的`handleLaunchActivity`处理
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            }
            break;
        }
    }
}

//ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ......
    //0. 创建Activity前初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();
    //1. 完成Activity对象的创建和启动过程
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        //2. 调用Activity的onResume这一生命周期
        handleResumeActivity(r.token, ... ,reason);
    } else {
        //3. 如果出错,会finishActivity
        ActivityManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null,
                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
    }
}

//ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //1. 从ActivityClientRecord中获取待启动的Activity的组件信息
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
    }
    ...
    //2. 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
    Activity activity = null;
    java.lang.ClassLoader cl = appContext.getClassLoader();
    // 实现简单,就是通过类加载器来创建Activity对象
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    ...
    /**============================================================
     * 3. 通过LoadedApk的makeApplication方法创建Application对象
     *  如果Application已经被创建,则不会重复创建-Application对象唯一
     *  1-内部是通过Instruction来完成,也是通过类加载器来实现
     *  2-Application创建好后,系统会通过Instruction的
     *    callApplicationOnCreate()来调用Application的onCreate()方法
     *============================================================*/
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    if (localLOGV) Slog.v(
            TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());
    /**===============================================================
     *4. 创建ContextImpl对象并通过Activity的attach方法来完成一些重要的数据初始化
     * -ContextImpl是Context的具体实现,ContextImpl通过Activity的attach方法和Activity建立关联
     * -attach方法中Activity会完成Window的创建并且建立自己和Window的关联
     *===============================================================*/
    ContextImpl appContext = createBaseContextForActivity(r);
    if (activity != null) {
        CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            ...
        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, r.configCallback);
            ...
        //5. 调用Activity的onCreate方法——Activity完成了整个启动过程
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
    }
    ...
    return activity;
}

//Activity.java
final void attach(Context context, ActivityThread aThread, ...) {
      //1. 建立Context和Activity的关联
      attachBaseContext(context);
      //2. 数据初始化: UI线程为当前线程, application等等
      mUiThread = Thread.currentThread();
      mApplication = application;
      ...
      //3. 创建Window(PhoneWindow)
      mWindow = new PhoneWindow(this);
      mWindow.setCallback(this);
      mWindow.setOnWindowDismissedCallback(this);
      mWindow.getLayoutInflater().setPrivateFactory(this);
      ...
      //4. 给Window设置WindowManager(从WindowManagerService获取)
      mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), ...);
      //5. 当前Window的容器是父Activity的Window
      if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
      }
      //6. 将当前Window的WindowManager保存到Activity内部
      mWindowManager = mWindow.getWindowManager();
      mCurrentConfig = config;
}

//ActivityThread.java
final void handleResumeActivity(IBinder token, ...) {
  /**
   * 1. 调用生命周期:onStart和onResume---通过Instrucmentation
   */
  ActivityClientRecord r = performResumeActivity(token, clearHide);
  //2. 获取到Window(在Activity的attach方法中创建了PhoneWindow)
  r.window = r.activity.getWindow();
  //3. 创建DecorView,设置为不可见INVISIBLE
  View decor = r.window.getDecorView();
  decor.setVisibility(View.INVISIBLE);
  a.mDecor = decor; //Activity内部保存了DecorView
  //4. 获取到WindowManager
  ViewManager wm = a.getWindowManager();
  //5. WM的addView方法将DecorView添加到Window中
  wm.addView(decor, l);
}

//ActivityThread.java
public final ActivityClientRecord performResumeActivity(IBinder token,boolean clearHide) {
  //1. 执行onStart和onRsume
  r.activity.performResume();
  ...
}

//Activity.java
final void performResume() {
  // 1. 通过Instrucmentation执行onStart()
  performRestart();
  // 2. 执行onResume方法
  mInstrumentation.callActivityOnResume(this);
}

Service

18、Service是什么?

  1. 一种计算型组件,用于在后台执行一系列计算任务(处理网络事务、播放音乐、文件读写、或者与ContentProvider交互)。
  2. Service具有两种状态:启动状态绑定状态
  3. 启动状态: 进行后台任务,Service本身运行在主线程,因此耗时操作需要在新线程中处理
  4. 绑定状态: 内部同样可以进行后台运算,但是此时外界可以很方便与Service通信
  5. Service的停止需要灵活采用stopService和unBindService才能完全停止

分类

19、Service的分类

  1. 本地服务
  2. 远程服务

20、本地服务是什么?

  1. 该类服务依赖在主进程上而不是独立的进程,一定程度上节约资源。
  2. 本地服务因为在同一进程内,不需要IPC和AIDL进行交互。bindService也方便很多。
  3. 缺点:限制性大,主进程被杀死后,服务便会终止
  4. 应用场景:需要姨父某个进程的服务,比如音乐播放。

21、远程服务是什么?

  1. 该服务是独立的进程,进程名为所在包名 + android:process指定的字符串
  2. 定义方式:用android:process=".service"
  3. 特点: 主进程被杀死后,该服务依然存在,不受其他进城影响,能为多个进程提供服务,具有灵活性。
  4. 会消耗更多资源,并且使用AIDL进行IPC比较麻烦,一般用于系统Service。
  5. 从Android 5.0开始,APP结束后会关闭相关进程树,因此相关的服务也会被杀死。

生命周期

22、Service的生命周期

  1. 仅仅是startService:onCreate()->onStartCommand()->onDestory()
  2. 仅仅是bindService:onCreate()->onBind()->onUnbind()->onDestory()
  3. 同时使用startService开启服务与bindService绑定服务:onCreate()->onStartCommand()->onBind()->onUnbind()->onDestory()

通信

23、Activity与Service间的通信方式

  1. Activity通过调用bindService,在ServiceConnection的onServiceConnected可以获取到Service的对象实例,然后就可以访问Service中的方法.(如果需要Service去主动通知Activity,可以通过回调来实现—在Activity的ServicConnection的onServiceConnected中去给Service设置实现的接口,该接口会在Service中被调用。)
  2. 通过广播
  3. 通过EventBus

启动模式

24、Service的启动方式有什么区别

  1. startService:Service与组件的生命周期无关,即使组件退出,Service依然存在。耗电,占内存。
  2. bindService:调用者退出后,Service也会退出。

25、startService

  1. Service无论调用多少次startServiceonCreate只会调用一次,onStartCommand会调用相应次数。
  2. Service无论调用多少次startService,只存在一个Service实例
  3. 结束Service只需要调用一次stopService或者stopSelf
  4. Activity的退出并不会导致Service的退出—除非在onDestoyr里面调用stopService,但是退出APP会导致Service1的退出!
  5. 系统资源不足的时候,服务可能会被Kill

26、bindService

  1. Service通过bindService启动,无论调用多少次,onCreate只会调用一次,且onStartCommand不会被调用。
  2. 如果调用Service的组件退出,如Activity,Service就会被停止。
  3. bindService开启的Service的通信比较方便,不需要AIDL和IPC

27、startService且同时bindService

  1. onCreate之调用一次。
  2. startService调用几次,onStartCommand会调用相同次数。
  3. bindService不会调用onStartCommand
  4. 调用unBindService不会停止Service,必须调用stopService和Service自身的stopSelf来停止。
  5. 如果想停止这种Service,unBindeServicestopService都需要调用,缺一不可。

28、同时开启和绑定有什么作用?

  1. 能让Service一直处于后台运行的状态,即使组件已经退出。
  2. 同时通过bindService能方便地与Service通信
  3. 相比于广播的方式,性能更高。

29、Service的注意点

  1. 手机发生旋转时,Activity的重新创建,会导致之前bindService建立的连接断开,Service会因为COntext的销毁而自动停止。

startService流程

30、Service的启动方法

Intent intent = new Intent(this, MyService.class);
startService(intent);
  1. Service有启动状态绑定状态
  2. 两个状态可以共存,Service可以既处于启动状态又处于绑定状态

31、Service的startService过程流程图和要点?

graph TD;
    1(1.startService);
    2(2.mBase.startService);
    3(3.startServiceCommon);
    4(4.ActivityManager.getService.startService);
    5(5.mServices.startServiceLocked);
    6(6.bringUpServiceLocked);
    7(7.realStartServiceLocked);
    8(8.app.thread.scheduleCreateService);
    9(9.sendServiceArgsLocked);
    10(10.handleMessage);
    11(11.handleCreateService);
    16(16.app.thread.scheduleServiceArgs);
    17(17.handleMessage);
    18(18.handleServiceArgs);
    19(19.onStartCommand);
    1-->2;
    2-->3;
    3-->4;
    4-->5;
    5-->6;
    6-->7;
    7-->8;
    7-->9;
    8-->10;
    10-->11;
    9-->16;
    16-->17;
    17-->18;
    18-->19;
  1. startService(ContextWrapper.java):Activity层层继承自ContextWrapper;内部交由ContextImplstartSertvice();典型的桥接模式
  2. mBase.startService(ContextImpl.java): 交给ContextImpl执行。
  3. startServiceCommon(ContextImpl.java): 通过ActivityManagerService启动服务;IPC
  4. startService(ActivityManagerService.java):通过ActiveServices进行后续工作—调用mServices.startServiceLocked
  5. startServiceLocked(ActiveServices.java): bringUpServiceLocked
  6. bringUpServiceLocked(ActiveServices.java): realStartServiceLocked
  7. realStartServiceLocked(ActiveServices.java): 1、app.thread.scheduleCreateService 2、sendServiceArgsLocked
  8. app.thread.scheduleCreateService(ActivityThread.java):1. 创建Service 2. 发送消息CREATE_SERVICE给Handler H
  9. sendServiceArgsLocked(): 用Service的其他方法(如onStartCommand)-IPC通信
  10. handleMessage(ActivityThread.java): 处理消息
  11. handleCreateService(ActivityThread.java): 处理第12、13、14、15 四步的工作, 进行Service的创建工作
  12. 16.app.thread.scheduleServiceArgs: IPC让ActivityThread只去执行其他的生命周期回调。发送消息给Handler H
  13. 17.handleMessage: 调用handleServiceArgs
  14. 18.handleServiceArgs: 执行其他的生命周期,如onStartCommand
  15. 19.onStartCommand: Service的回调方法
graph TD;
    11(11.handleCreateService);
    12(12.cl.loadClass);
    13(13.makeApplication);
    14(14.service.attach);
    15(15.service.onCreate);
    11-->12;
    11-->13;
    11-->14;
    11-->15;
  1. handleCreateService(ActivityThread.java): 处理第12、13、14、15 四步的工作
  2. cl.loadClass().newInstance(): 类加载器创建Service实例。
  3. packageInfo.makeApplication: 用LoadedApk创建Application实例
  4. service.attach: 创建ContextImpling建立Context和Service的联系。
  5. service.onCreate(): Service的onCreate(), 并且将Service对象存储到ActivityThread中的一个列表中

32、ActiveServices是什么?

  1. 辅助ActivityManagerService进行Service管理
  2. 包括:启动、绑定、停止等

33、ServiceRecord是什么?

  1. 描述一个Service记录,官场整个启动过程

34、ContextWrapper是什么?

  1. ContextWrapper是Context实现类ContextImpl的包装类
  2. Activity、Service等都是直接或者间接继承自ContextWrapper

35、ContextWrapper为什么是典型桥接模式?

36、桥接模式和代理模式的区别?

源码

37、Service的启动过程源码详细分析

   /**
     * ======================================
     * 1. Activty层层继承自ContextWrapper
     * 2. Activty的startService()方法来自于ContextWrapper
     * 3. ContextWrapper最终由mBase(ContextImpl)完成-典型桥接
     * ======================================
     */
    //ContextWrapper.java
    public ComponentName startService(Intent service) {
        //1. mBase就是Context的实现ContextImpl对象(也就是Activity创建时关联的对象)
        return mBase.startService(service);
    }

    //ContextImpl.java:直接调用startServiceCommon
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);
    }

    //ContextImpl.java
    private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
        ......
        //1. 让`ActivityManagerService`启动一个Service服务
        ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, ...省略...);
        ......
    }

    //ActivityManagerService.java
    public ComponentName startService(IApplicationThread caller, Intent service, ...) {
        /**====================================
         * 1. 通过mService(ActiveServices)完成后续过程
         * 2. ActiveServices是辅助AMS进行Service管理的类
         *     -包括:启动、绑定、停止
         * 3. `startServiceLocked`方法尾部会调用`startServiceInnerLocked`
         *=====================================*/
        res = mServices.startServiceLocked(caller, service, ...,userId);
    }

    //ActiveServices.java
    ComponentName startServiceInnerLocked(...,ServiceRecord r) {
        ......
        /**=========================================
         * ServiceRecord描述的是一个Service记录(贯穿整个启动过程)
         * 1. startServiceInnerLocked并没有完成具体启动工作,而是把后续任务交给了bringUpServiceLocked
         * 2. bringUpServiceLocked内部调用`realStartServiceLocked`
         * 3. realStartServiceLocked真正启动了Service
         *==========================================*/
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        ......
        return r.name;
    }

    //ActiveServices.java
    private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) {
        ......
        /**========================================================
         * 创建了Service对象,并且调用了onCreate()方法-IPC通信
         * 1. app.thread对象是IApplicationThread类型(Binder)
         * 2. 具体实现是ActivityThread(继承了ApplicationThreadNative)
         *========================================================*/
        app.thread.scheduleCreateService(r, r.serviceInfo, ......);
        ......
        //2. 用于调用Service的其他方法(如onStartCommand)-IPC通信
        sendServiceArgsLocked(r, execInFg, true);
        ......
    }

    //ActivityThread.java的内部类:ApplicationThread
    public final void scheduleCreateService(IBinder token, ...,int processState) {
        updateProcessState(processState, false);
        CreateServiceData s = new CreateServiceData();
        s.token = token;
        s.info = info;
        s.compatInfo = compatInfo;
        /**========================================
         *  1. 发送消息给Handler H处理
         *  2. H会接受消息,并且调用ActivityThread的handleCreateService
         *========================================*/
        sendMessage(H.CREATE_SERVICE, s);
    }

    /**====================================
     * 完成Service最终启动工作
     * //ActivityThread.java
     *=====================================*/
    private void handleCreateService(CreateServiceData data) {
        //1. 通过类加载器创建Service实例
        Service service = null;
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
        //2. 创建Application对象并调用其onCreate方法(Application是唯一的不会重复创建)
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        //3. 创建ContextImpl对象并通过Service的attach方法建立两者关系(类似Activity的过程)
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
        //4. 调用service的onCreate方法,并且将Service对象存储到ActivityThread中的一个列表中
        service.onCreate();
        mServices.put(data.token, service);
        ......
    }

    /**=============================================================
     * ActivityThread中还会通过handleServiceArgs方法调用Service的onStartCommand
     *=============================================================*/
    private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        ......
        //1. Service的onStartCommand方法
        res = s.onStartCommand(data.args, data.flags, data.startId);
        ......
    }

bindService流程

38、Service绑定流程图分析

graph TD;
    1(ContextWrapper.bindService);
    2(ContextImpl.bindServiceCommon);
    3(LoadedApk.getServiceDispatcher);
    4(ActivityManager.getService.bindService);
    5(mServices.bindServiceLocked);
    6(r.app.thread.scheduleBindService);
    7(Handler H);
    8(handleBindService);
    9(mServices.get);
    10(service.onBind);
    11(AMS.publishService);
    12(c.conn.connected);
    13(sd.connected);
    14(mActivityThread.post);
    15(doConnected);
    16(onServiceConnected);
    1-->2;
    2-->3;
    2-->4;
    4-->5;
    5-->6;
    6-->7;
    7-->8;
    8-->9;
    8-->10;
    8-->11;
    11-->12;
    12-->13;
    13-->14;
    14-->15;
    15-->16;
  1. bindService(): 调用了ContextWrapper的该方法。
  2. bindServiceCommon(): ContextImpl的该方法,执行了第3,4两步的工作
  3. getServiceDispatcher(): 将客户端的ServiceConnection对象转换为ServiceDispatcher内部类InnerConnection对象,需要借助Binder才能让远程服务端调用自己的方法。
  4. ActivityManager.getService().bindService: 通过AMS执行bindService方法。
  5. mServices.bindServiceLocked(): 调用到ActiveServices的该方法。
  6. r.app.thread.scheduleBindService: 通过IPC去调用ActivityThread内部类Application的该方法。
  7. 本质都是通过Handler H的handleMessage()去进行处理
  8. handleBindService: 进行第9、10、11 三步的任务1.根据token取出Service 2.调用Service的onBind方法 3.通过IPC去告知客户端已经连接成功,并且执行onServiceConnected
  9. Service s = mServices.get(data.token): 利用token取出Service
  10. IBinder binder = s.onBind(data.intent): 知性Service的onBind方法
  11. ActivityManager.getService().publishService: Service在执行onBind后已经处于绑定状态,但是此时客户端并不知道,需要通过Binder去执行ServiceConnection的onServiceConnected方法。
  12. c.conn.connected: 调用ServiceDispatcher.InnerConnectionconnected()【IPC】
  13. sd.connected: 调用LoadedApk.java的内部类ServiceDispatcher的方法
  14. mActivityThread.post: mActivityThread就是Handler H
  15. doConnected: 最终调用ServiceConnection的onServiceConnected方法

39、如何让远程服务端调用客户端的ServiceConnection中的方法?

  1. 无法直接让远程服务端使用
  2. 需要借助Binder才能让远程服务端毁掉自己的方法
  3. ServiceDispatcher的内部类InnerConnection就起到了Binder的作用
  4. ServiceDispatcher起到连接ServiceConnection和InnerConnection的作用

40、getServiceDispatcher的原理

  1. 使用ArrayMap来:存储应用当前活动的ServiceConnection和ServiceDispatcher的映射关系
  2. key = ServiceConnection, value = ServiceDispatcher
  3. 根据ServiceConnection去查询是否有对应的ServiceDispatcher,存在就直接返回ServiceDispatcher的InnerConnection。
  4. 不存在,就新建ServiceDispatcher,并将映射关系存放到Map中。

41、何时Service处于绑定状态(何时执行的onBind方法)?

  1. 执行到ActivityThreadhandlerBindService()里,会获取到Service并且执行Service的onBind方法,此时就处于了绑定状态。

42、何时执行的ServiceConnection的onServiceConnected方法?

  1. AMS的publishService: 需要在Service进入绑定状态后,告知客户端已经完成连接。
  2. 【IPC】LoadedApk的ServiceDispatcher的connected方法
  3. 通过Handler H,最终在ActivityThread内部执行了onServiceConnected方法。

43、Service在ActivityThread中的存储?

  1. ActivityThread通过ArrayMap存储了IBinder和Service的映射关系。
  2. key = IBinder, value = Service
  3. 在handlerCreateService中创建好Service后,会将IBinder-Service的映射关系保存到Map中。
  4. AMS通过Binder去执行Service的任务比如执行Service的onBind方法,需要知道IBinder对应的是哪个Service,就利用到了ArrayMap存储的映射关系。
源码

44、Service的绑定过程源码

/**
 * ==============================================
 * 1. bindService最终也是调用的ContextWrapper的方法
 * 2. 与启动过程类似, mBase是ContextImpl最终会调用自身的bindServiceCommon方法
 * //ContextWrapper.java
 * =============================================
 */
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    return mBase.bindService(service, conn, flags);
}

//ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
        handler, UserHandle user) {
    /**======================================================================
     * 1. 将客户端的ServiceConnection对象转化为`ServiceDispatcher.InnerConnection`对象
     *  -ServiceConnection必须借助于Binder才能让远程服务端回调自己的方法
     *  -ServiceDispatcher的内部类InnerConnection就起到了Binder的作用
     *  -ServiceDispatcher起到连接ServiceConnection和InnerConnection的作用
     *======================================================================*/
    IServiceConnection sd;
    sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    //2. 通过ActivityManagerService完成Service的绑定过程
    int res = ActivityManager.getService().bindService(... , service,...);
    ......
}

//LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) {
    /**================================
     * 1.mServices是ArrayMap:存储应用当前活动的ServiceConnection
     *    和ServiceDispatcher的映射关系
     *================================*/
    synchronized (mServices) {
        LoadedApk.ServiceDispatcher sd = null;
        //2. 获取`映射关系`的map
        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
        if (map != null) {
            //3. 通过ServiceConnection去查询是否有ServiceDispatcher
            sd = map.get(c);
        }
        //4. 不存在ServiceDispatcher,新建ServiceDispatcher对象,
        if (sd == null) {
            sd = new ServiceDispatcher(c, context, handler, flags);
            if (map == null) {
                map = new ArrayMap<>();
                //6. 将该`映射关系`与Context放置到ArrayMap中
                mServices.put(context, map);
            }
            //5. key=ServiceConnection,value=ServiceDispatcher,建立映射关系
            map.put(c, sd);
        }
        //7. 返回ServiceDispatcher内部保存的InnerConnection
        return sd.getIServiceConnection();
    }
}

//ActivityManagerService.java
public int bindService(IApplicationThread caller, IBinder token, Intent service,...) {
    ......
    /**=========================
     * ActiveServices的方法:
     *  1. bindServiceLocked
     *  2. bringUpServiceLocked
     *  3. realStartServiceLocked
     *  4. 最后都是通过ActivityThread来完成Service实例的创建
     *      并且执行Services的onCreate方法
     *  * Service绑定与启动的不同在于会调用app.thread的scheduleBindService方法
     *      (在ActiveServices的requestServiceBindingLocked中调用)
     *============================*/
    return mServices.bindServiceLocked(caller, token, service,...);
}

//ActiveServices.java
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,...) {
    ......
    //ActivityThread内部类:`ApplicationThread`——中一系列`schedule`方法之一,最终通过Handler H进行中转,最终交给handleBindServices
    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState);
    ......
}

//ActivityThread
private void handleBindService(BindServiceData data) {
    //1. 根据token取出Service
    Service s = mServices.get(data.token);
    if (s != null) {
        if (!data.rebind) {
            /**================================
             * 2. 调用Service的onBind方法
             *  -此时Service就已经处于绑定状态,但此时客户端并不知道连接成功
             *  -因此必须调用客户端ServiceConnection中的onServiceConnected
             *=================================*/
            IBinder binder = s.onBind(data.intent);
            /**=======================================
             * 3. ActivityManagerService的publishService
             *  -1.会执行客户端ServiceConnection中的onServiceConnected
             *  -2.保证Service的onBind方法之调用一次(多次绑定同一个Service)
             *  -3.最终将具体任务交给ActiveServices的publishServiceLocked方法
             *========================================*/
            ActivityManager.getService().publishService(data.token, data.intent, binder);
        }
    }
    ......
}

//ActiveServices.java
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    ......
    /**===================================
     * 1. c是ConnectionRecord
     * 2. c.conn是ServiceDispatcher.InnerConnection
     * 3. service就是Service的onBind方法返回的Binder对象
     *==================================*/
    c.conn.connected(r.name, service, false);
    ......
}

//LoadedApk.java的内部类ServiceDispatcher的内部类InnerConnection
private static class InnerConnection extends IServiceConnection.Stub {
    ......

    public void connected(ComponentName name, IBinder service, boolean dead) {
        LoadedApk.ServiceDispatcher sd = mDispatcher.get();
        if (sd != null) {
            //1. 调用ServiceDispatcher的方法
            sd.connected(name, service, dead);
        }
    }
}

//LoadedApk.java的内部类: ServiceDispatcher
public void connected(ComponentName name, IBinder service, boolean dead) {
    /**=========================================================
     *1. mActivityThread是一个Handler,其实就是ActivityThread中的H
     *2. 最终RunConnection通过H的post方法从而运行在主线程中
     *3. 因此客户端ServiceConnection就是在主线程被回调
     *========================================================*/
    mActivityThread.post(new RunConnection(name, service, 0, dead));
}

//LoadedApk.java内部类ServiceDispatcher的内部类: RunConnection
private final class RunConnection implements Runnable {
    ......
    /**
     * =========================================================
     * 1. 本质调用ServiceDispatcher的doConnected
     * 2. ServiceDispatcher内部拥有客户端的ServiceConnection
     * ========================================================
     */
    public void run() {
        if (mCommand == 0) {
            doConnected(mName, mService, mDead);
        } else if (mCommand == 1) {
            doDeath(mName, mService);
        }
    }
}

//LoadedApk.java内部类: ServiceDispatcher
public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ....
    if (service != null) {
        //1. 可以通过客户端的ServiceConnection调用onServiceConnected
        mConnection.onServiceConnected(name, service);
    }
}

Broadcast

45、BroadcastReceiver是什么?

  1. 一种消息型组件,用于在不同组件甚至不同应用间传递消息
  2. 静态注册: 在AndroidManifest中注册广播,会在应用安装时被系统解析,不需要启动应用就可以接收到相应广播(从Android 3.1开始默认不给不在运行的应用发送广播)
  3. 动态注册: Context.registerReceiver()进行注册,Context.unRegisterReceiver()解除注册. 需要APP启动才能注册并且接收广播。
  4. 广播发送通过Context的一系列send方法完成
  5. 发送和接收过程的匹配通过广播接收者的intent-filter来描述

分类

46、广播分为几种

  1. 普通广播
  2. 有序广播

47、普通广播是什么?

  1. 调用sendBroadcast()发送

48、有序广播是什么?

  1. 调用sendOrderedBroadcast()发送
  2. 广播接收者会按照priority优先级从大到校进行排序
  3. 优先级相同的广播,动态注册的广播优先处理
  4. 广播接收者还能对广播进行截断和修改

49、广播的发送和接收原理

  1. 继承BroadcastReceiver,在onReceive()中实现接收到广播后应该进行的操作。
  2. 通过Binder机制ActivityManagerService注册广播。
  3. 通过Binder机制ActivityManagerService发送广播。
  4. ActivityManagerService会查找符合广播条件(IntentFilter/Permission)的所有BroadcastReceiver, 并将这些广播接受器存放到队列中。
  5. 遍历队列中所有的BroadcastReceiver,并将广播发送给该接收器【IPC】。
  6. 最终通过Handler H回调其onReceive()方法。

50、BroadcasReceiver和LocalBroadcastReceiver

  1. BroadcasReceiver是跨应用广播,利用Binder机制实现。
  2. LocalBroadcastReceiver应用内广播,利用Handler实现。利用IntentFiltermatch功能,提供消息的发布与接收,实现应用内通信,效率较高。

51、本地广播的优点

  1. 效率更改。
  2. 发送的广播不会离开我们的应用,不会泄露关键数据。
  3. 其他程序无法将广播发送到我们程序内部,不会有安全漏洞。

注册方式

52、广播两种注册方式的区别

  1. 静态注册:常驻系统,不受组件生命周期的影响,耗电,占内存
  2. 动态注册:非常驻系统,组件结束,广播就结束。但是在组件结束前,一定要释放广播,避免内存泄露和崩溃。

53、广播的静态注册过程:

  1. 安装应用时由系统自动完成注册
  2. 具体是由PMS(Package Manager Service)来完成注册过程
  3. 本质其他三大组件的注册都是在安装时由PMS解析并注册

动态注册

54、广播动态注册的流程图

graph TD;
1(registerReceiver-ContextWrapper);
2(registerReceiver-ContextImpl);
3(registerReceiverInternal-ContextImpl);
4(获取IIntentReceiver对象);
5(ActivityManager.getService.registerReceive);
6(mRegisteredReceivers.put);
7(mReceiverResolver.addFilter);
1-->2;
2-->3;
3-->4;
3-->5;
5-->6;
5-->7;
  1. registerReceiver: ContextWrapper.java, 层层调用
  2. registerReceiver: ContextImpl.java, 层层调用
  3. registerReceiverInternal: ContextImpl.java 进行下面4、5的工作
  4. mPackageInfo.getReceiverDispatcher/LoadedApk.ReceiverDispatcher : 获取到IIntentReceiver对象
  5. ActivityManager.getService().registerReceiver(): 【IPC】调用AMS的registerReceiver方法,进行下面6、7的工作
  6. mRegisteredReceivers.put(): 将InnerReceiver对象进行存储(该对象与BroadcastReceiver对象相对应)
  7. (mReceiverResolver.addFilter(): 存储IntentFilter

55、为什么需要将BroadcastReceiver转换为IIntentReceiver?

  1. BroadcastReceiver作为组件不能直接进行IPC,需要进行中转
  2. IIntentReceiver是Binder接口,具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver
  3. ReceiverDispatcher中同时保存了 BroadcastReceiver和InnerReceiver,接收广播时ReceiverDispatcher可以很方便调用BroadcastReceiver的onReceive()方法
  4. Service也有ServiceDispatcher和内部类InnerConnection(Binder接口),原理相同

56、动态注册的本质是什么?

  1. 将BoradcastReceiver对应的Binder对象InnerReceiver存储到ActivityManagerService的Map中
  2. 将IntentFilter存储到AMS中
动态注册源码

57、广播的动态注册过程:

/**
 * =================================
 * 1. 动态注册是从ContextWrapper的registerReceiver方法开始
 * 2. 之后直接交给ContextImpl完成
 * //ContextWrapper.java
 * =================================
 */
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    //1. mBase = ContextImpl
    return mBase.registerReceiver(receiver, filter);
}

//ContextImpl.java
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,......) {
    return registerReceiverInternal(receiver, ......);
}

//ContextImpl.java
private Intent registerReceiverInternal(BroadcastReceiver receiver, ......) {
    IIntentReceiver rd = null;
    if (receiver != null) {
        if (mPackageInfo != null && context != null) {
            //1. 从mPackageInfo获取IIntentReceiver对象
            rd = mPackageInfo.getReceiverDispatcher(receiver, context, scheduler, ......);
        } else {
            /**==============================================================================
             *2.从mPackageInfo获取IIntentReceiver对象
             * 1-采用IIntentReceiver而不是BroadcastReceiver是因为这是IPC过程
             * 2-BroadcastReceiver作为组件不能直接进行IPC,需要进行中转
             * 3-IIntentReceiver是Binder接口,具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver
             * 4-ReceiverDispatcher中同时保存了 BroadcastReceiver和InnerReceiver,接收广播时ReceiverDispatcher
             *     可以很方便调用BroadcastReceiver的onReceive()方法
             * 5-可以发现Service也有ServiceDispatcher和内部类InnerConnection(Binder接口),原理相同
             *===============================================================================*/
            rd = new LoadedApk.ReceiverDispatcher(receiver, context, scheduler, null, true)
                    .getIIntentReceiver();
        }
    }
    //3. 通过ActivityManagerService, 远程进行注册
    final Intent intent = ActivityManager.getService().registerReceiver(
            mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
            broadcastPermission, userId, flags);
        ......
}

//ActivityManagerService.java:广播完成注册
public Intent registerReceiver(IApplicationThread caller, ...,IIntentReceiver receiver, ...) {
    ......
    //1. 存储远程的InnerReceiver对象(本地的BroadcastReceiver对应的对象)
    mRegisteredReceivers.put(receiver.asBinder(), rl);
    //2. 存储IntentFiler对象
    BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
            permission, callingUid, userId, instantApp, visibleToInstantApps);
    rl.add(bf);
    mReceiverResolver.addFilter(bf);
    ......
}

广播发送

58、广播发送/接收的流程图(普通广播)

graph TD;
1(sendBroadcast);
2(ActivityManager.getService.broadcastIntent);
3(broadcastIntentLocked);
4(intent.addFlags);
5(过滤出广播接受器);
6(enqueueOrderedBroadcastLocked);
7(scheduleBroadcastsLocked);
8(mHandler.sendMessage);
9(processNextBroadcast);
10(deliverToRegisteredReceiverLocked);
11(performReceiveLocked);
12(app.thread.scheduleRegisteredReceiver);
13(receiver.performReceive);
14(mActivityThread.post);
15(receiver.onReceive);
1-->2;
2-->3;
3-->4;
3-->5;
3-->6;
3-->7;
7-->8;
8-->9;
9-->10;
10-->11;
11-->12;
12-->13;
13-->14;
14-->15;
  1. sendBroadcast: 调用顺序-Activity->ContextWrapper->ContextImpl
  2. ActivityManager.getService().broadcastIntent(……): 直接向AMS发起一个异步请求用于发送广播
  3. broadcastIntentLocked: 进行第4、5、6、7的工作—添加标志位(不给已经停止的应用发送广播)、根据Intent-Fillter找到匹配的BroadcastReceiver、经过过滤后将
  4. intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES): 从Android 3.1开始默认不会给已经停止的应用发送广播。
  5. 根据intent-filter查找出匹配的广播接收者, 过滤出所有符合条件的BroadcastReceiver
  6. queue.enqueueOrderedBroadcastLocked: 会将满足条件的广播接收者都加入到BroadcastQueue中
  7. queue.scheduleBroadcastsLocked:会将广播发送到BroadcastQueue中的所有广播接收者中。
  8. mHandler.sendMessage: 发送消息
  9. processNextBroadcast: 取出广播并且发送给所有接收者。
  10. deliverToRegisteredReceiverLocked: 发送广播
  11. performReceiveLocked: 通过IPC发送给ActivityThread
  12. app.thread.scheduleRegisteredReceiver: 通过InnerReceiver实现广播的接收
  13. receiver.performReceive: ReceiverDispatcherd的performReceive方法,通过Handler H去投递一个Runnable
  14. mActivityThread.post: 通过Handler H 的post方法投递Runnable
  15. receiver.onReceive: 执行BroadcastReceiver的onReceive方法
源码

59、广播的发送和接收过程源码(普通广播为例):

  1. 通过sendBroadcast发送广播时,AMS会查找出匹配的广播接收者并将广播发送给它们处理
  2. 广播分为:普通广播、有序广播和粘性广播
/**
 * ==================================================
 * 1. 广播的发送开始于ContextWrapper的sendBroadcast方法
 * 2. 最终会交给ContextImpl的sendBroadcast方法去处理
 * // ContextImpl.java
 * ==================================================
 */
public void sendBroadcast(Intent intent) {
    //1. 直接向AMS发起一个异步请求用于发送广播
    ActivityManager.getService().broadcastIntent(......);
    ......
}
//ActivityManagerService.java
public final int broadcastIntent(IApplicationThread caller, Intent intent, ......) {
    ....
    int res = broadcastIntentLocked(callerApp, ......);
}
//ActivityManagerService.java
final int broadcastIntentLocked(ProcessRecord callerApp, ......) {
    intent = new Intent(intent);
    /**==============================================================
     *1. 默认情况下广播不会发送给已经停止的应用(从Android 3.1开始)
     * Intent中新增两个标记:
     *  FLAG_EXCLUDE_STOPPED_PACKAGES-不包含已经停止应用
     *  FLAG_INCLUDE_STOPPED_PACKAGES-包含已经停止应用
     * -如果两个标记共存,则以FLAG_INCLUDE_STOPPED_PACKAGES为准
     * -停止状态为:1-应用安装后未运行 2-应用被手动或者其他应用强制停止
     *==============================================================*/
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    ......
    /**================================================
     *2. 根据intent-filter查找出匹配的广播接收者
     *3. 进过一系列过滤后,将满足条件的广播接收者添加到`BroadcastQueue`
     *4. BroadcastQueue就会将广播发送给相应的广播接收者
     *===============================================*/
    if ((receivers != null && receivers.size() > 0)
            || resultTo != null) {
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, ......);

       ......
        queue.enqueueOrderedBroadcastLocked(r);
        //4. BroadcastQueue就会将广播发送给相应的广播接收者
        queue.scheduleBroadcastsLocked();
    }
    ......
    return ActivityManager.BROADCAST_SUCCESS;
}
//BroadcastQueue.java
public void scheduleBroadcastsLocked() {
    //1. 发送消息,BroadcastQueue收到消息后会调用processNextBroadcast方法
    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
}
//BroadcastQueue.java
final void processNextBroadcast(boolean fromMsg) {
    synchronized (mService) {
        BroadcastRecord r;
        ......
        //1. 普通广播处理
        while (mParallelBroadcasts.size() > 0) {
            //2. 无序广播存储在mParallelBroadcasts中
            r = mParallelBroadcasts.remove(0);
            final int N = r.receivers.size();
            //3. 取出广播并发送给他们所有的接受者
            for (int i = 0; i < N; i++) {
                Object target = r.receivers.get(i);
                //4. 发送广播
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter) target, false, i);
            }
            addBroadcastToHistoryLocked(r);
        }
        ......
    }
}
//BroadcastQueue.java
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) {
    performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, ......);
}
//BroadcastQueue.java
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, ...) {
    ......
    //1. app.thread为ActivityThread,会调用其中方法
    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.repProcState);
}
//ActivityThread.java
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, ......) {
    updateProcessState(processState, false);
    //1. 通过`InnerReceiver`实现广播的接收, 内部会调用ReceiverDispatcher的performReceive方法
    receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky, sendingUser);
}
//LoadedApk.java内部类ReceiverDispatcher
public void performReceive(Intent intent, int resultCode, String data, ......) {
    //1. 创建Args对象
    final Args args = new Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);
    ......
    /**=========================================================
     * 2. 通过mActivityThread的post方法来执行args中的逻辑
     *   -mActivityThread是Handler(也就是ActivityThread中的Handler H)
     *   -Args中实现了Runnable接口-在广播接受线程中执行了onReceive方法
     *========================================================*/
    if (intent == null || !mActivityThread.post(args.getRunnable())) {
        ......
    }
}
//LoadedApk.java内部类ReceiverDispatcher.Args
final class Args extends BroadcastReceiver.PendingResult {
    .......

    public final Runnable getRunnable() {
        return () -> {
            //1. 执行了BroadcastReceiver的onReceive方法
            final BroadcastReceiver receiver = mReceiver;
            ......
            receiver.onReceive(mContext, intent);
            ......
        };
    }
}

ContentProvider

60、ContentProvider是什么?

  1. 一种数据共享型组件
  2. 内部需要实现增删改查四种操作
  3. 内部的insert\delete\update\query方法需要处理好线程同步,因为这些方法都在Binder线程池中调用

61、ContentProvider要点

  1. ContentProvider所在进程启动时,就会同时启动并且发布到AMS中
  2. ContentProvider的onCreate要先于Application的onCreate执行

启动

62、ContentProvider的启动流程

  1. ActivityThreadmain方法为应用启动时的入口,main是静态方法——会创建ActivityThread的实例,并且创建主线程消息队列
  2. 然后会在ActivityThreadattach()方法中远程调用AMSattachApplication方法并将ApplicationThread对象提供给AMS
  3. ApplicationThread是Binder对象,Binder接口是IApplicationThread,主要用于ActivityThreadAMS之间的通信
  4. AMSattachApplication中会调用ApplicationThreadbindApplication方法(IPC过程),bindApplication的逻辑会通过ActivityThread中的Handler H切换到ActivityThread中的handleBindApplication去处理
  5. handleBindApplication中会创建Application对象并且加载ContentProvider
  6. 加载ContentProvider后,才会调用ApplicationonCreate方法

数据访问

63、ContentProvider的数据访问

  1. ContentProvider启动后,外界就可以通过提供的接口进行增删改查
  2. 外界无法直接访问ContentProvider,需要通过AMS根据Uri来获取对应的ContentProvider的Binder接口IContentProvider
  3. 然后通过IContentProvider来访问其数据源
/**
 * =============================================================================
 * 1. 其他应用通过AMS来访问指定的ContentProvider
 * 2. 通过AMS获得ContentProvider的Binder对象:IContentProvider
 * 3. IContentProvider的具体实现ContentProvider.Transport(继承自ContentProviderNative)
 * 以query为例: 最终会通过IPC调用到ContentProvider.Transport的query方法
 * //ContentProvider.java内部类: Transport
 * =============================================================================
 */
public Cursor query(String callingPkg, Uri uri, String[] projection, ......) {
    ......
    //1. 调用了ContentProvider的query方法
    Cursor cursor = ContentProvider.this.query(uri, projection, queryArgs, CancellationSignal.fromTransport(cancellationSignal));
    ......
}

数据解析

64、ContentProvider的数据访问解析

  1. 访问ContentProvider需要通过ContentResolver,这是一个抽象类
  2. Context的getContentResolver()本质获取的是ApplicationContentResolver对象(ContextImpl的内部类)
  3. ContentProvider所在进程未启动时,第一次访问会触发所在进程的启动和ContentProvider的创建。
  4. 例如query方法,首先会获取IContentProvider对象,最终通过acquireProvider来获取ContentProvider

65、ContentProvider访问和创建的流程图

graph TD;
1(1.acquireProvider);
2(2.mMainThread.acquireProvider);
3(3.acquireExistingProvider);
4(4.ActivityManager.getService.getContentProvider);
5(5.getContentProviderImpl);
6(6.startProcessLocked);
7(7.main)
8(8.new ActivityThread)
9(9.thread.attach)
10(10.Looper)
11(11.ActivityManager.getService.attachApplication);
12(12.thread.bindApplication);
13(13.sendMessage);
14(14.handleBindApplication);
15(15.创建ContextImpl对象);
16(16.makeApplication);
17(17.installContentProviders);
18(18.callApplicationOnCreate);
19(19.installProvider);
20(20.AMS.publishContentProviders);
21(21.创建ContentProvider);
22(22.localProvider.attachInfo);
1-->2;
2-->3;
2-->4;
4-->5;
5-->6;
6-->7;
7-->8;
7-->9;
7-->10;
9-->11;
11-->12;
12-->13;
13-->14;
14-->15;
14-->16;
14-->17;
14-->18;
17-->19;
17-->20;
19-->21;
19-->22;
  1. acquireProvider:;直接调用ActivityThread的方法; 位于ContextImpl.java的内部类:ApplicationContentResolver
  2. mMainThread.acquireProvider: 进行3、4
  3. acquireExistingProvider(): 查询是否存在需要的ContentProvider,存在就直接返回
  4. ActivityManager.getService().getContentProvider: 发送请求让AMS启动需要的ContentProvider
  5. getContentProviderImpl: 调用startProcessLocked去启动ContentProvide所在进程,然后才会启动ContentProvider
  6. startProcessLocked: 1. 会先启动ContentProvider所在的进程,然后才会启动ContentProvider 2. 主要是通过Process的start方法来完成新进程的启动 3. 新进程启动后入口方法在ActivityThread的main方法
  7. main: 进行第8、9、10三个工作1.创建ActivityThread实例 2.初始化工作 3.Looper相关
  8. new ActivityThread(): 创建实例
  9. thread.attach: 一系列初始化工作
  10. Looper: Looper相关工作
  11. ActivityManager.getService().attachApplication(): 通过AMS进行处理—【IPC】
  12. thread.bindApplication(): 通过【IPC】又交给ContentProvider进程进行bindApplication操作
  13. sendMessage(H.BIND_APPLICATION): 发送BIND_APPLICATION
  14. handleBindApplication: 进行15、16、17、18的工作,主要是创建Application和COntentProvider
  15. ContextImpl.createAppContext: 创建ContextImpl对象
  16. makeApplication: 创建Application对象
  17. installContentProviders: 进行19、20,启动当前进程的ContentProvider并调用其onCreate方法
  18. callApplicationOnCreate: 调用Application的onCreate方法
  19. installProvider: 遍历当前进程的Provider列表,调用installProvider进行启动。进行21、22
  20. AMS.publishContentProviders: 将已经启动的ContentProvider保存在AMS的ProviderMap中 外部调用者就可以直接从AMS中获取ContentProvider
  21. 类加载器创建ContentProvider
  22. localProvider.attachInfo: 通过ContextProvider的方法调用了onCreate方法

源码

66、ContentProvider源码解析

    //ContextImpl.java的内部类:ApplicationContentResolver
    protected IContentProvider acquireProvider(Context context, String auth) {
        //1. 直接调用`ActivityThread`的方法
        return mMainThread.acquireProvider(context, ContentProvider.getAuthorityWithoutUserId(auth), resolveUserIdFromAuthority(auth), true);
    }

    //ActivityThread.java
    public final IContentProvider acquireProvider(Context c, String auth, int userId, boolean stable) {
        //1. 查找是否已经存在需要的ContenProvider
        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
        if (provider != null) {
            //2. 存在就直接返回——ActivityThread通过mProviderMap来存储已经启动的ContentProvider
            return provider;
        }
        ContentProviderHolder holder = null;
        //3. 不存在就发送请求让`AMS`启动需要的`ContentProvider`
        holder = ActivityManager.getService().getContentProvider(getApplicationThread(), auth, userId, stable);
        ......
        //4. 最后修改引用计数
        holder = installProvider(c, holder, holder.info, true, holder.noReleaseNeeded, stable);
        return holder.provider;
    }

    //ActivityManagerService.java
    public final ContentProviderHolder getContentProvider(IApplicationThread caller, String name, int userId, boolean stable) {
        ...
        return getContentProviderImpl(caller, name, null, stable, userId);
    }

    //ActivityManagerService.java
    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, ...) {
        ContentProviderRecord cpr;
        ContentProviderConnection conn = null;
        ProviderInfo cpi = null;
        ......
        //1. 会先启动ContentProvider所在的进程,然后才会启动ContentProvider
        /**==================================================================
         * 1. 会先启动ContentProvider所在的进程,然后才会启动ContentProvider
         * 2. startProcessLocked中主要是通过Process的start方法来完成新进程的启动
         * 3. 新进程启动后入口方法在ActivityThread的main方法(个人认为这是ContentProvider的进程不是我们自己应用的)
         *==================================================================*/
        proc = startProcessLocked(cpi.processName,
                cpr.appInfo, false, 0, "content provider",
                new ComponentName(cpi.applicationInfo.packageName,
                        cpi.name), false, false, false);
        ......
        return cpr != null ? cpr.newHolder(conn) : null;
    }

    //ActivityThread.java
    public static void main(String[] args) {
        ...
        //1. 首先会创建ActivityThread实例
        ActivityThread thread = new ActivityThread();
        //2. 然后调用attach-进行一系列初始化
        thread.attach(false);
        //3. 然后开始消息循环
        Looper.prepareMainLooper();
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();
        ...
    }

    //ActivityThread.java
    private void attach(boolean system) {
        ......
        //1. 将ApplicationThread对象传输给AMS(IPC)
        final IActivityManager mgr = ActivityManager.getService();
        mgr.attachApplication(mAppThread);
        ......
    }

    //ActivityManagerService.java
    public void attachApplication(IApplicationThread thread) {
        attachApplicationLocked(thread, callingPid);
    }

    //ActivityManagerService.java
    private boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ......
        thread.bindApplication(processName, appInfo, providers, ......);
        ......
    }

    //ActivityThread.java内部类:ApplicationThread
    public final void bindApplication(String processName, ApplicationInfo appInfo,......) {
        ......
        //1. 发送消息给Handler H(ActivityThread)
        sendMessage(H.BIND_APPLICATION, data);
    }
    //ActivityThread.java

    /**
     * ==============================================
     * -完成了Application的创建
     * -以及ContentProvider的创建
     * //ActivityThread.java
     * ================================================
     */
    private void handleBindApplication(AppBindData data) {
        ...
        //1. 创建ContextImpl对象和Instrumentation
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
        final ClassLoader cl = instrContext.getClassLoader();
        //Instrumentation
        mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        //2. 创建Application对象
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        //3. 启动当前进程的ContentProvider并调用其onCreate方法
        if (!data.restrictedBackupMode) {
            if (!ArrayUtils.isEmpty(data.providers)) {
                installContentProviders(app, data.providers); //启动并且调用onCreate
                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10 * 1000);
            }
        }
        //4. 调用Application的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);
    }
    //ActivityThread.java
    private void installContentProviders(Context context, List<ProviderInfo> providers) {
        final ArrayList<ContentProviderHolder> results = new ArrayList<>();
        //1. 遍历当前进程的Provider列表
        for (ProviderInfo cpi : providers) {
            //2. 调用installProvider进行启动
            ContentProviderHolder cph = installProvider(context, null, cpi, ......);
            if (cph != null) {
                cph.noReleaseNeeded = true;
                results.add(cph);
            }
        }
        //2. 将已经启动的ContentProvider保存在AMS的ProviderMap中, 外部调用者就可以直接从AMS中获取ContentProvider
        ActivityManager.getService().publishContentProviders(getApplicationThread(), results);
        ......
    }
    //ActivityThread.java
    private ContentProviderHolder installProvider(Context context, ......) {
        ContentProvider localProvider = null;
        IContentProvider provider;
        ...
        //1. 通过类加载器完成了ContentProvider对象的创建
        final java.lang.ClassLoader cl = c.getClassLoader();
        localProvider = (ContentProvider) cl.loadClass(info.name).newInstance();
        provider = localProvider.getIContentProvider();
        if (provider == null) {
            return null;
        }
        //2. 通过ContextProvider方法调用了onCreate方法
        localProvider.attachInfo(c, info);
        ...
    }

Fragment

67、Fragment的常见问题,以及如何处理?

  1. getActivity()空指针:常见于进行异步操作的时候,此时如果Fragment已经onDetach(),就会遇到。解决办法:在Fragment里面使用一个全局变量mActivity,可能会导致内存泄露。但是比崩溃更好。
  2. 视图重叠:主要是因为FragmentonCreate()中没有判断saveInstanceSate == null,导致重复加载了同一个Fragment

序列图解析四大组件流程

68、Activity的启动

Created with Raphaël 2.1.2 Activity Activity ActivityManagerService ActivityManagerService ActivityStackSupervisor ActivityStackSupervisor ActivityThread ActivityThread 1.startActivity 2.startActivityForResult 3.mInstrumentation. execStartActivity 【IPC】4.ActivityManager. getService() 5.startActivity() 6.checkStartActivityResult 7.realStartActivityLocked() 【IPC】8.app.thread. scheduleLaunchActivity 9.sendMessage(H.LAUNCH_ACTIVITY) 10.Handler H 11.handleMessage() 12.handleLaunchActivity() 13.WindowManagerGlobal. initialize() (12) 14.performLaunchActivity() (12) 15.handleResumeActivity() (12) 16.getPackageInfo() (14) 17.newActivity() (14) 18.makeApplication() (14) 19.createBaseContextForActivity() (14) 20.activity.attach() (14) 21.callActivityOnCreate() (14) 22.attachBaseContext() (20) 23.new PhoneWindow() (20) 24.mWindow. setWindowManager() (20) 25.保存WM到Activity内部 (20)

13.创建Activity前初始化WindowManagerGlobal
14.完成Activity对象的创建和启动过程
15.调用Activity的onResume这一生命周期
17.通过类加载器来创建Activity对象
18.通过LoadedApk的makeApplication方法创建Application对象(唯一),并会调用onCreate()
19.创建ContextImpl,并调用attach
20.关联了Context和Activity,并且创建Window加载WM等初始化工作
21.调用Activity的onCreate方法

69、Service的启动
AT: ActivityThread

Created with Raphaël 2.1.2 AT[Service进程] AT[Service进程] Activity[客户端] Activity[客户端] ActivityManagerService ActivityManagerService ActiveServices ActiveServices null 1.启动 2.startService() -ContextWrapper 3.mBase.startService() -ContextImpl 【IPC】 4.ActivityManager.getService() 5.startService() 6.mService. startServiceLocked() 7.bringUpServiceLocked() 8.realStartServiceLocked() 【IPC】9.app.thread.scheduleCreateService()-ApplicationThread的方法 10.sendMessage (H.CREATE_SERVICE) 11.handleCreateService() 12.类加载器创建Service对象 13.makeApplication 14.service.attach(context...) 15.service.onCreate(); mServices.put() 【IPC】16.sendServiceArgsLocked() 17.handleServiceArgs() 18.s.onStartCommand

11.Handler H接受并且处理消息,最终调用handleCreateService()
13.makeApplication(创建Application对象并调用onCreate()-若已经存在则不创建)
14.创建ContextImpl并调用attach方法-建立ContextImpl和Service的联系
15.service.onCreate(),并将Service添加到ActivityThread内部的Service列表中
16.sendServiceArgsLocked()-内部最终调用Service的其他方法(onStartCommand等)

70、Service的绑定

Created with Raphaël 2.1.2 ActivityThread[客户端] ActivityThread[客户端] Activity Activity ContextImpl ContextImpl AMS AMS ActiveServices ActiveServices ActivityThread[Service端] ActivityThread[Service端] 1.启动Activity 2.bindService() 3.bindServiceCommon() 4.mPackageInfo. getServiceDispatcher 【IPC】5.ActivityManager. getService() 6.bindService() 7.mService. bindServiceLocked() 8.requestServiceBindingLocked() 9.realStartServiceLocked() 【IPC】10.app.thread.scheduleBindService() 11.handleBindService() 12.s.onBind(data.intent) 【IPC】13.ActivityManager. getService() 14.publishService() 15.publishServiceLocked() 【IPC】16.c.conn.connected() 17.mActivityThread. post() 18.doConnected() 19.mConnection. onServiceConnected

2 最终是会调用ContextImpl的bindServiceCommon方法
4.ServiceConnection需要借助binder才能让远程服务回调自己的方法(借助于ServiceDispatcher.InnerConnection)
10.scheduleBindService会发送消息,最终由handleBindService处理
12.调用Service的onBind方法-绑定成功
13.绑定成功后需要通知客户端:最终调用客户端ServiceConnection中的onServiceConnected
16.c.conn是ServiceDispatcher.InnerConnection(ServiceConnection的Binder中转对象),最终调用ServiceDispatcher的connected
17.mActivityThread就是ActivityThread的Hanlder H
18.通过post最终运行在主线程
19.调用客户端的onServiceConnected方法

71、广播的动态注册

Created with Raphaël 2.1.2 Activity Activity ContextImpl ContextImpl ActivityManagerService ActivityManagerService 1.registerReceiver() 2.registerReceiverInternal() 3.mPackageInfo.getReceiverDispatcher() 4.new LoadedApk. ReceiverDispatcher(). getIIntentReceiver() 5.ActivityManager.getService() 6.registerReceiver() 7.mRegisteredReceivers. put(receiver.asBinder()); 8.存储IntentFiler对象

1.动态注册从ContextWrapper开始,之后直接交给ContextImpl完成
3.已有,从mPackageInfo获取IIntentReceiver对象
4.没有则新建IIntentReceiver对象,本质是为了IPC通信需要进行中转,ReceiverDispatcher中同时保存了 BroadcastReceiver和InnerReceiver
7.存储远程的InnerReceiver对象(本地的BroadcastReceiver对应的对象)

72、广播的发送和接收

Created with Raphaël 2.1.2 ActivityThread[接收方] ActivityThread[接收方] Activity Activity ActivityManagerService ActivityManagerService BroadcastQueue BroadcastQueue null 1.sendBroadcast()- ContextImpl 【IPC】2.ActivityManager. getService() 3.broadcastIntent() 4.broadcastIntentLocked() 4-1.intent.addFlags() 4-2.根据intent-filter查找出 匹配的广播接收者 4-3.将满足条件的广播接收者 添加到BroadcastQueue 4-4.queue. scheduleBroadcastsLocked() 5.mHandler.sendMessage 6.processNextBroadcast() 6-1.mParallelBroadcasts.remove(0) 6-2.r.receivers.get(i)遍历接收者 6-3.deliverToRegisteredReceiverLocked() 7.performReceiveLocked() 【IPC】8.app.thread.scheduleRegisteredReceiver() LoadedApk的内部类: ReceiverDispatcher中 9.receiver. performReceive() 10.mActivityThread. post(args.getRunnable()) 11.receiver. onReceive();

5.默认FLAG_EXCLUDE_STOPPED_PACKAGES-广播不会发送给已经停止的应用
4-4.BroadcastQueue就会将广播发送给相应的广播接收者
6.接收消息并且处理
6-1.取出无序广播列表中的广播
8.通过InnerReceiver实现广播的接收, 内部会调用ReceiverDispatcher的performReceive方法
10.通过Hanlder H的post方法来执行args中的逻辑
11.LoadedApk.java内部类ReceiverDispatcher的内部类Args,主要是执行BroadcastReceiver的接收方法

73、ContentProvider的机制

Created with Raphaël 2.1.2 ContextImpl[使用者] ContextImpl[使用者] ActivityThread ActivityThread AMS AMS ActivityThread[新] ActivityThread[新] 1.getContentResolver(). query() 2.acquireProvider() 3.mMainThread. acquireProvider() 4.acquireExistingProvider() 存在直接返回provider 【IPC】5.ActivityManager. getService() 6.getContentProvider() 7.getContentProviderImpl() 8.startProcessLocked() 【新进程入口】9.main 9-1.new ActivityThread() 9-2.thread. attach(false) 9-3.Looper. prepareMainLooper() 10.attach() 【IPC】11.ActivityManager. getService() 12.attachApplication() 13.attachApplicationLocked() 【IPC】14.thread.bindApplication() 15.sendMessage (H.BIND_APPLICATION) 16.handleBindApplication 16-1.创建ContextImpl对象 16-2.创建Instrumentation 16-3.makeApplication() 16-4.installContentProviders() 16-5.mInstrumentation. callApplicationOnCreate() 17.installContentProviders() 17-1.installProvider() 18.localProvider.attachInfo() 【IPC】17-2.ActivityManager.getService() 19.publishContentProviders()

1.获得ContextImpl的内部类:ApplicationContentResolver
5.不存在ContentProvider让MAS启动需要的ContentProvider
8.通过Process的start方法来完成新进程的启动
9-1.首先会创建ActivityThread实例
9-2.然后调用attach-进行一系列初始化
9-3.然后开始消息循环
12.将ApplicationThread传输给AMS
15. 发送消息给Handler H
16. 完成了Application的创建以及ContentProvider的创建
16-3. makeApplication()创建Application对象
16-4. 启动ContentProvider并调用onCreate方法
16-5. 调用Application的onCreate方法
17-1. 遍历当前进程的Provider列表并调用installProvider()
18.创建ContentProvider对象,并调用onCreate方法
19.将已经启动的ContentProvider保存在AMS的ProviderMap中,外部调用者就可以直接从AMS中获取ContentProvider

参考和学习资料

  1. 剖析Activity、Window、ViewRootImpl和View之间的关系
  2. Service 启动和绑定解析
  3. Service
  4. 桥接模式和代理模式的区别
  5. 代理模式与桥接模式 备忘

猜你喜欢

转载自blog.csdn.net/feather_wch/article/details/81136168