0
点赞
收藏
分享

微信扫一扫

android Framework 探究 - 浅谈AIDL和Binder

冶炼厂小练 2022-04-23 阅读 52
androidjava

开头

下面是计划,哎…万事开头难,看了知识A发现知识B还不了解,计划也是修修改改

计划

任务阶段目标
1,进程通讯机制 - binder 和 aidl (binder不能恋战)这很重要,理解了这个才能看懂系统服务间大量的进程间调用关系
2,Android系统的启动流程理解init进程,zygote,systemServer的启动流程,承担的角色
3,AMS的启动流程理解AMS从哪里启动,负责启动和管理哪些服务
4,ActivityTask,ActivityRecord,ActivityStackSupervisor理解Activity的基本数据结构和管理方式
5,Activity的启动流程梳理startActivity的调用逻辑
6,SurfaceFling,Choreographer渲染机制Jank的理解和计算方式
7,WMS窗口管理机制(后面可能有调整)
未完待续

大佬们的指导思想

在迷茫的时候多看一些过来人的意见
Android Framework 如何学习,如何从应用深入到Framework?

我起跑时跌倒的经历

当然每个人的知识水平不同,我个人偏上层。

从Binder开始

binder是我们入门Framework的最重要的基础之一,至少理解了binder在系统服务间的跨进程调用,否则很难看懂。

从应用开发者角度开始认识Binder

怎样学习binder?我推荐你先看完这个
Binder学习指南

一,Java层的几个类和概念

  • android.os.IBinder.java : 代表进程通讯的能力。
  • android.os.IInterface.java :客户端和服务端的接口定义(远程接口有什么样的功能)。
  • android.os.Binder.java :可以进程通讯的对象。

角色概念

我想大家都看过科幻剧,一般都有真人投影会议的桥段。

  • Proxy : 代理。影分身,和真人一模一样,客户端通过代理对象访问服务端,感官上和真人说话一模一样。
  • Stub :存根。一般是服务端来实现,就是真人本尊。

方法

  • transact :传送门,开始传送…
  • onTransact :传送门,到达了…

二,从一个AIDL的demo引入思考

demo结构,一个app模块,一个service模块

app模块

service模块

AIDL内容:我利用模板生成,为了好区分,我把方法名修改为add。

// IMyAidlInterface.aidl
package com.demo.service;

// Declare any non-default types here with import statements

interface IAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void add(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

build后,编译器会帮助我们生成aidl对应的IAidlInterface.java文件,不贴出全部了,重点我截取片段出来。

android的编译器一股脑全部生成在一个类,原本是这样的:

public interface IAidlInterface extends android.os.IInterface{
	...
	public static abstract class Stub extends android.os.Binder implements com.demo.service.IAidlInterface{
	...
		private static class Proxy implements com.demo.service.IAidlInterface{
		}
	}
}

嵌套了两层内部类,其实这个java文件也可以自己编写,我更喜欢这样看:

public interface IAidlInterface extends android.os.IInterface{}
public abstract class Stub extends android.os.Binder implements com.demo.service.IAidlInterface{}
private class Proxy implements com.demo.service.IAidlInterface{}

在这里插入图片描述


Framework中binder的调用

一,binder在AMS中的样子

在这里插入图片描述

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    /**
     * Retrieve the system's default/global activity manager.
     * 通过这个静态方法,App就可以调用ams在IActivityManager注册的接口。
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
........
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
         	// 向SM大管家获取AMS的binder引用
            IBinder b = ServiceManager.getService("activity");
      		...
      		//如果是客户端调用,就返回代理对象。
            IActivityManager am = asInterface(b);
            ...
            return am;
        }
    };
}
    

二,APP获取AMS的Binder代理,进行调用

例如:Activity启动过程中,会调用AMS中去,那么Client访问Server的目的就达成了。

Instrumentation.java

 ActivityManagerNative.getDefault().startActivities(whoThread,who.getBasePackageName(),intents,resolvedTypes,token, options, userId);

三,AMS获取APP的Binder代理

AMS在完成Activity的启动后,需要回调通知app,app也要像AMS那样注册到SM吗?不是的,app在调用AMS的方法时,把自己的binder传给了AMS。

ActivityThread.java

    public static void main(String[] args) {
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);//启动的时候调用了这个方法。
        ...
    }
 	private void attach(boolean system){
 		 final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            	//这个调用了AMS的方法,传入了一个mAppThread,我们紧接着去看AMS是怎么实现的
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
 	}
private class ApplicationThread extends ApplicationThreadNative{}
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
public interface IApplicationThread extends IInterface

基本就和AMS的实现一样,说明ApplicationThread也是一个S端。

传递的逻辑,如图

在这里插入图片描述

紧接着就有一次对app的跨进程调用,调用了bindApplication方法。

ActivityManagerService.java#attachApplicationLocked

调用bindApplication方法的逻辑,如图

在这里插入图片描述
理解完上面的调用很重要,至此我们至少熟悉了binder跨进程中调用的流程,这下我们就可以继续下一步正式进行系统启动流程的分析了。

呜谢:

Android Framework 如何学习,如何从应用深入到Framework?

举报

相关推荐

0 条评论