Android Framework 架构介绍,Binder理解

一,Android Framework架构介绍

1.Android系统架构

Android本质就是在标准的Linux系统上增加了Java虚拟机Dalvik/ART,并在Dalvik/ART虚拟机上搭建了一个JAVA的application framework,所有的应用程序都是基于JAVA的application framework之上。

Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。

Android架构

 

Linux 内核

原生 C/C++ 库 + Android Runtime

Java API 框架(Android Framework 框架层)

系统应用

1)APPLICATION (System Apps

该层提供一些核心应用程序包,主要为系统中的应用,如桌面,闹铃,设置,日历,电话,短信等系统应用。同时,应用开发工程师设计和编写属于的应用程序也在这一层。

2)APPLICATION FRAMEWORK(Java API 框架

应用框架层为开发人员提供了可以开发应用程序所需要的API,我们平常开发应用程序都是调用的这一层所提供的API,当然也包括系统的应用。这一层的是由Java代码编写的,所以可以称为Java Framework。应用框架层是系统的核心部分,一方面向上提供接口给应用层调用,另一方面向下与C/C++程序库以及硬件抽象层等进行衔接

应用程序框架层包括活动管理器、位置管理器、包管理器、通知管理器、资源管理器、 电话管理器、窗口管理器、内容提供者、视图系统和XMPP服务十个部分。

这里写图片描述
Java FrameWork


3)系统运行库层(C/C++程序库和Android运行时库)

① C/C++程序库

Android 包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者提供服务。以下是一些核心库:

这里写图片描述
C/C++程序库

② Android Runtime运行时库

运行时库又分为核心库和ART(5.0系统之后,Dalvik虚拟机被ART取代)。核心库提供了Java语言核心库的大多数功能,这样开发者可以使用Java语言来编写Android应用。相较于JVM,Dalvik虚拟机是专门为移动设备定制的,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。而替代Dalvik虚拟机的ART的机制与Dalvik不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用

4)Linux Kernel

Android 的核心系统服务基于Linux 内核,在此基础上添加了部分Android专用的驱动。系统的安全性、内存管理、进程管理、网络协议栈和驱动模型等都依赖于该内核。Linux内核也是作为硬件与软件栈的抽象层。

5)各层之间的联系

从下至上排序,Linux层为第1层,系统运行库层为第2层,JavaFrameWork层为第3层,System Apps层为第4层;

Android的第一层是用C语言实现,第二层由C和C++实现,第3、4层主要是用Java实现的;

第1、2层之间,从linux的操作系统的角度来看,是由内核空间和用户空间的分界线;

第2、3层之间是本地代码层和java代码层的接口;

第3、4层之间,是android的系统API的接口;

第一层运行于内核空间,第2、3、4层运行于用户空间

 

2.Android系统启动过程

 Android启动过程包含从Linux内核加载到Home应用程序启动的整个过程。

1)Android是基于linux内核的系统平台,启动时,首先通过Bootloader(系统加载器),加载Linux内核。在Linux加载启动时,与普通的Linux启动过程相同,先初始化内核,然后调用init进程(Linux用户空间中第一个进程,是所有进程的父进程)。

2) Init进程启动Zygote。init进程启动. init进程主要来创建和挂载启动所需的文件目录,启动属性服务(类似于windows的注册表),启动Zygote进程。

3) Zygote(孵化器)进程的建立是真正的Android运行空间,Zygote孵化第一个进程SystemServer,SystemServer启动各种系统服务线程。

SystemServer进程在Android的运行环境中扮演了"神经中枢"的作用,APK应用中能够直接交互的大部分系统服务都在该进程中运行,常见的比如WindowManagerServer(WMS)、ActivityManagerSystemService(AMS)、PackageManagerServer(PMS)等,这些系统服务都是以一个线程的方式存在于SystemServer进程中。

SystemService会启动Binder线程池 创建SystemServiceManage对系统服务的创建启动和生命周期进程管理,并启动各种java层系统服务,接着会调用WMS,AMS等服务的systemReady()完成启动.

4) 当以上服务线程都启动后,AMS以systemReady调用完成最后启动,在ActivityManagerService的systemReady方法中调用startHomeActivityLocked来启动Action为Intent.ACTION_MAIN Category为Intent.CATEGORY_HOME的应用,也就是Launcher所配置的标签,启动第一个Activity。至此,Android系统的启动完成。

BootLoader --> Linux kernel --> init --> SystemServer --> Launcher

三,Binder理解

以下内容基于《Android Framework精编内核解析

1)Binder概述

Android系统中,每个应用程序是由Android的ActivityServiceBroadcastContentProvider这四剑客的中一个或多个组合而成,这四剑客所涉及的多进程间的通信底层都是依赖于Binder IPC机制。例如当进程A中的Activity要向进程B中的Service通信,这便需要依赖于Binder IPC。不仅于此,整个Android系统架构中,大量采用了Binder机制作为IPCInter-Process Communication 进程间通信)方案,当然也存在部分其他的IPC方式,比如Zygote通信便是采用socket。

Binder作为Android系统提供的一种IPC机制,无论从事系统开发还是应用开发,都应该有所了解,这是Android系统中最重要的组成,也是最难理解的一块知识点,错综复杂。

IPC原理

从进程角度来看IPC机制

binder_interprocess_communication
Android进程间IPC

 

每个Android的进程,只能运行在自己进程所拥有的虚拟地址空间。对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间,当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间彼此是不能共享的,而内核空间却是可共享的。Client进程向Server进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的,Client端与Server端进程往往采用ioctl(ioctl 是设备驱动程序中设备控制接口函数,打开关闭,读写)等方法跟内核空间的驱动进行交互。

Binder通信原理

Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及Binder驱动,其中ServiceManager用于管理系统中的各种服务。架构图如下所示:

ServiceManager
Binder通信C/S架构

可以看出无论是注册服务和获取服务的过程都需要ServiceManager,需要注意的是此处的Service Manager是指Native层的ServiceManager(C++),并非指framework层的ServiceManager(Java)。ServiceManager是整个Binder通信机制的大管家,是Android进程间通信机制Binder的守护进程,要掌握Binder机制,首先需要了解系统是如何首次启动Service Manager当Service Manager启动之后,Client端和Server端通信时都需要先获取Service Manager接口,才能开始通信服务

图中Client/Server/ServiceManage之间的相互通信都是基于Binder机制。既然基于Binder机制通信,那么同样也是C/S架构,则图中的3大步骤都有相应的Client端与Server端。

注册服务:Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。

获取服务:Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。

使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。

图中的Client,Server,Service Manager之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder驱动进行交互的,从而实现IPC通信方式。其中Binder驱动位于内核空间,Client,Server,Service Manager位于用户空间Binder驱动和Service Manager可以看做是Android平台的基础架构,而Client和Server是Android的应用层,开发人员只需自定义实现client、Server端,借助Android的基本平台架构便可以直接进行IPC通信。

C/S模式

BpBinder(客户端)和BBinder(服务端)都是Android中Binder通信相关的代表。

  • client端:BpBinder.transact()来发送事务请求;
  • server端:BBinder.onTransact()会接收到相应事务。

2)Binder 驱动概述

Binder 驱动是 Android 专用的,但底层的驱动架构与 Linux 驱动一样。binder驱动在以 misc 设备进行注册,作为虚拟字符设备,没有直接操作硬件,只是对设备内存的处理。主要是驱动设备的初始化(binder_init),打开 (binder_open),映射(binder_mmap),数据操作(binder_ioctl)。

Binder 驱动的 init 、 open 、 mmap 、 ioctl这 4 个核心方法:

初始化(binder_init),为了注册 misc 设备,初始化字符设备;
打开 (binder_open),打开 binder 驱动设备;
映射(binder_mmap),申请内存空间,实现用户空间的 Buffer 和内核空间的Buffer 同步操作的功能;
数据操作(binder_ioctl),该函数负责在两个进程间收发 IPC 数据和 IPC reply 数据,执行相应的 ioctl 操作;

3)ServiceManager

① 启动 ServiceManager

ServiceManager 是 Binder IPC 通信过程中的守护进程,本身也是一个 Binder服务,ServiceManager 本身工作相对简单,其核心功能:查询和注册服务。对于 Binder IPC
通信过程中,其实更多的情形是 BpBinder 和 BBinder 之间的通信,比如ActivityManagerProxy 和 ActivityManagerService 之间的通信等。

注册服务:记录服务名和 handle 信息,保存到 svclist 列表;
查询服务:根据服务名查询相应的的 handle 信息。

ServiceManger 集中管理系统内的所有服务,通过权限控制进程是否有权注册服务,通过字符串名称来查找对应的Service; 由于ServiceManger进程建立跟所有向其注册服务的死亡通知, 那么当服务所在进程死亡后, 会只需告知ServiceManager。每个 Client 通过查询 ServiceManager 可获取 Server 进程的情况,降低所有 Client 进程直接检测会导致负载过重。

获取 ServiceManager

获取 Service Manager 是通过 defaultServiceManager() 方法来完成,当进程注册服务(addService)或 获取服务(getService)的过程之前,都需要先调用
defaultServiceManager()方法来获取 gDefaultServiceManager 对象。对于gDefaultServiceManager 对象,如果存在则直接返回;如果不存在则创建该对象,创建过程包括调用 open()打开 binder 驱动设备,利用 mmap()映射内核的地址空间。

4)framework层分析

主要分析Binder在java framework层的框架

Binder架构

binder在framework层,采用JNI技术来调用native(C/C++)层的binder架构,从而为上层应用程序提供服务。 native层中,binder是C/S架构,分为Bn端(Server)和Bp端(Client)。对于java层在命名与架构上非常相近,同样实现了一套IPC通信架构。

java_binder
framework Binder架构图

 

图中红色代表整个framework层 binder架构相关组件;

Binder类代表Server端,BinderProxy类代码Client端;

图中蓝色代表Native层Binder架构相关组件;

上层framework层的Binder逻辑是建立在Native层架构基础之上的,核心逻辑都是交予Native层方法来处理。

framework层的ServiceManager类与Native层的功能并不完全对应,framework层的ServiceManager类的实现最终是通过BinderProxy传递给Native层来完成的。

如何使用AIDL(重点)

AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写。其主要作用是用于进程间的通讯。

既然在Android系统中,进程间相互独立,但是有时候我们又有应用间进行互动的需求,比较传递数据或者任务委托等,AIDL就是为了满足这种需求而诞生的。通过AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法,从而满足进程间通信的需求。进程间相互传递的数据类型如下:

  • 八种基本数据类型:byte、char、short、int、long、float、double、boolean
  • String,CharSequence
  • 实现了Parcelable接口的数据类型
  • List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
  • Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象

编写代码:

创建两个工程,一个作为服务端,一个作为客户端,客户端绑定服务端service,然后调用方法向服务端获取书籍名称,向服务端添加书籍序号。

1)创建服务端

① 在Android Studio中 src目录上右键创建一个AIDL文件 并命名,完成后会再main下自动生成一个aidl目录,该目录的包名和java下的包名是一致的。

创建完成后样式如下图所示:

每次生成的.aidl文件后我们需要build一下才能让系统生成自后我们能使用文件。因为在进程间通信中真正起作用的并不是 AIDL 文件,而是系统据此而生成的文件,在Android Studio下,我们可以在build/generated/aidl目录下找到这些Java文件。之后需要使用到当中的内部静态抽象类 Stub
当然我们可以在所有aidl文件写完再build,也可以每次写完一个build一下。

② 我们在java对应bean目录下 生成一个实体类,这里我们写一个书籍类;

我们要在AIDL中用到这个实体类,所以需要用Parcelable序列化该实体类:

③ 接着我们要把用到的bean类在上面创建的aidl包下相同目录下创建对应实体类的aidl文件,并把它改为声明parcelable数据类型的AIDL文件;

注意这里的parcelable是小写。

④ 然后可以再开始写的IMyAidlInterface.aidl里定义能被客户端调用的接口:

至此,我们的aidl文件写完了, 写完后我们make project或者make对应的module让漏掉的文件自动生成。

⑤ 接下来 在java下创建一个类IBinder继承IMyAidlInterface.aidl对应的IMyAidlInterface.Stub,实现对应的方法:

⑥ 然后使用服务暴露接口给外部,创建一个服务RemoteService 继承Service,实现对应方法,绑定MyBinder:

⑦ 在清单文件里注册服务:

到这里服务端的完成了.接下来是创建客户端。

2)创建Client客户端

① 新建一个工程作为客户端,我们把服务端的 的aidl整个包下所有东西都拷贝到新项目中,然后make project或者make对应的module:

② 如果aidl有用到bean实体类,我们也要把这些实体类照搬过来:

③ 接下来,我们就可以在客户端的activity里连接远程服务 实现aidl通信:

具体代码如下:

public class ClientActivity extends AppCompatActivity {

    private IMyAidlInterface iMyAidlInterface;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.txt);
        bind();
    }

    private boolean connected = false;
    private ServiceConnection serviceConnection;
    private void bind() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.aidl", "com.example.aidl.RemoteService"));
        bindService(intent, serviceConnection = new ServiceConnection() {

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.d("chin", "onServiceConnected");
                connected = true;
                iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
                try {
                    textView.setText(iMyAidlInterface.getName());
                    iMyAidlInterface.setNumber(56);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d("chin", "onServiceDisconnected");
                iMyAidlInterface = null;
                connected = false;
            }
        }, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
}

在onServiceConnected()回调中,我们使用IMyAidlInterface.Stub.asInterface(service)方法返回我们的接口的引用。接着客户端就可以通过它来与服务端通信了。

先运行服务端,在运行客户端,得到结果如下:

  • 首先,我们Client客户端,接收到服务端发送出来的书名;
  • 接着,服务端收到客户端重新定义的书的序列号;

 

 

参考文章

Android Framework入门介绍

Framework学习(一)Android 系统架构

android系统启动流程

Android AIDL 使用

想进阶,AIDL你得学习一下

 

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Android Framework是指Android操作系统中提供的一套API和工具集合,可以帮助开发者快速构建Android应用程序。底层开发主要涉及到Android Framework层的源代码和相关文档,本质上是深入了解Android操作系统原理和架构,具有较高的技术门槛。 探索Android Framework底层开发可以帮助开发者更好地理解Android的运行原理,提高代码质量和效率。具体来说,需要掌握以下几个方面: 1. Java编程语言:Android开发是基于Java的,需要掌握Java的语法和开发环境。 2. Android系统架构:了解Android系统的四层架构是必要的,包括应用层、框架层、系统运行库和Linux内核。 3. Android Framework层的API:掌握常用的Android Framework层的API,如Activity、Service、BroadcastReceiver等。 4. Android框架源代码:深入了解Android框架层的源码实现,可以帮助开发者更好地掌握Android系统的工作机制和运行原理。 5. Android开发工具:熟练掌握Android Studio等开发工具,可以提高Android开发的效率和质量。 总之,探索Android Framework底层开发是一个深入了解Android操作系统原理和架构的过程,需要不断学习和实践才能不断提高自己的技术水平。 ### 回答2: Android 底层开发需要具备一定的计算机基础知识和编程技能。Android 应用程序由 Android FrameworkAndroid 应用程序层组成,Android Framework 包含了很多核心组件和类库,例如 Activity、Service 和 ContentProvider 等。 若要深入探究 Android Framework,我们需要从底层的 Linux 内核开始了解。因为 Android 基于 Linux 内核设计,所以我们需要了解 Linux 内核的结构和原理,熟悉 Linux 的命令行操作。接着,我们需要掌握 Java 编程语言的基础知识,了解 Android 的四大组件和应用开发模式。 此外,我们还需要了解 Android Framework 最核心部分的 Binder 服务。Binder 运行在 Linux 内核空间中,用于在 Android 应用程序层和 Android Framework 层之间传递信息。理解 Binder 的运作原理将对深入理解 Android Framework 有很大帮助。 探索 Android Framework 底层开发需要不断学习和实践。建议参考 Android 官方文档、查阅相关书籍和博客,积极参与开源社区和论坛,不断提高自己的技能和水平。只有积累了足够的经验和技能,才能够开发出高质量的 Android 应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值