• Android


    Android核心分析之AMS

    App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程

    App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。

    打开一个APP

    Launcher

    Launcher负责桌面图标的显示和控制,本质上也是一个应用程序,和我们的App一样,也是继承自Activity

    以双击打开一个APP为例:

    不管在哪里点击图标,都会调用

    mLauncher.startActivitySafely(v, appInfo.intent, appInfo);

    这个方法,最后调用startActivityForResult()

    而startActivityForResult()调用的是mInstrumentation.execStartActivity()。

    Instrumentation

    Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
     
    AMS是董事会,负责指挥和调度的,ActivityThread是老板,虽然说家里的事自己说了算,但是需要听从AMS的指挥,而Instrumentation则是老板娘,负责家里的大事小事,但是一般不抛头露面,听一家之主ActivityThread的安排。
     

    AMS和ActivityThread之间的Binder通信

    mInstrumentation.execStartActivity()接下来调用了这个方法

    ActivityManagerNative.getDefault()
                    .startActivity

    这里的ActivityManagerNative.getDefault返回的就是ActivityManagerService的远程接口,即ActivityManagerProxy。

    再看ActivityManagerProxy.startActivity(),在这里面做的事情就是IPC通信,利用Binder对象,调用transact(),把所有需要的参数封装成Parcel对象,向AMS发送数据进行通信。

    ActivityManagerNative源码:

    public abstract class ActivityManagerNative extends Binder implements IActivityManager
    {
    
    //从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口
     static public IActivityManager getDefault() {
            return gDefault.get();
        }
    
     //通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得
     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;
            }
        };
    }
    
    
    //最终返回的还是一个ActivityManagerProxy对象
    static public IActivityManager asInterface(IBinder obj) {
            if (obj == null) {
                return null;
            }
            IActivityManager in =
                (IActivityManager)obj.queryLocalInterface(descriptor);
            if (in != null) {
                return in;
            }
    
         //这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信
            return new ActivityManagerProxy(obj);
        }
    
    
    }

    很清楚看到ActivityManagerNative继承Binder,是Binder本地对象。IActivityManager是远程接口,代表AMS能提供的功能。

    ActivityManagerProxy是AMS的远程代理对象,Activity可以通过代理对象调用AMS提供的接口中方法。

    所以App与AMS通过Binder进行IPC通信

     

    AMS向ActivityThread通信

    以上解释了activity向AMS通信的方法,

    如果AMS想要通知ActivityThread做一些事情,应该咋办呢?

    还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。

    private class ApplicationThread extends ApplicationThreadNative {}
    
      public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
    
      class ApplicationThreadProxy implements IApplicationThread {}

    AMS接收到客户端的请求之后,会如何开启一个Activity?

    可以看上面那个图,大致就是AMS得到activity栈的引用,然后根据启动模式添加到栈中,最后回调applicationThread执行原activity的pause

    广播

    为什么需要广播

      广播是操作系统framework层对观察者模式(observer)最常用的实现方式

      一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。

    广播发送的api有:
    •sendBroadcast
    •sendOrderBroadcast
    •sendStickyBroadcast
    监听广播的方式有:
    •动态注册使用registerReceiver方式
    •静态注册在AndroidManifest.xml中定义BroadcastReceiver类并实现

    广播有哪几种

         广播有无序广播、有序广播和粘性广播,其中粘性广播需要有BROADCAST_STICKY权限

    Service

    Service是什么

        Service是Android系统的组件之一,和Activity,Broadcast,Conent Provider并称Android四大组件,Service是不可见的,是没有界面的,是在后台运行的,Service一般处理比较耗时以及长时间运行的操作

    Service的启动有两种方式:

     1. startService主要用于启动一个服务执行后台任务,不进行通信,停止服务使用stopService

     2. bindService该方法启动的服务可以获得该service的状态,停止服务使用unbindService

     

  • 相关阅读:
    Kafka副本管理—— 为何去掉replica.lag.max.messages参数
    Kafka0.8.2.1删除topic逻辑
    【原创】如何确定Kafka的分区数、key和consumer线程数
    【原创】Kafka console consumer源代码分析(二)
    QGIS源码解析和二次开发
    点云数据中的三维信息提取pcl
    Halcon10.0 + VS2010
    Halcon链接库
    python调用Opencv库和dlib库
    cvtColor
  • 原文地址:https://www.cnblogs.com/qlky/p/7296164.html
Copyright © 2020-2023  润新知