1.一文分析Binder机制和AIDL的源码理解
2.AndroidFramework ä¹å¯å¨ ServiceManager
3.log4j2(ä¸) è·å ILoggerFactory
4.深度分析Binder线程池的启动流程
5.Android Binder Hookçå®ç°
6.androidåLinuxçåºå«ï¼
一文分析Binder机制和AIDL的理解
深入了解Android进程间通信机制,如同破解系统奥秘的源码钥匙,它在源码探索和问题解决中扮演着核心角色。源码Binder机制,源码源自OpenBinder,源码正是源码mvc的源码这个领域的主角,它弥补了Linux原生通信方式在性能和安全性的源码短板。它的源码运作涉及驱动层与应用层的无缝对接,包括与系统服务如Activity Manager Service (AMS) 的源码深度协作。 Binder,源码作为Java编写的源码通信工具包,是源码Android多进程通信的基石。尽管AIDL(Android Interface Definition Language)常用于简化这一过程,源码但并非不可或缺。源码让我们通过一个实例,源码不依赖AIDL,来揭示Binder通信的内在机制。想象一个简单的场景:一个客户端(ClientBinder)与服务端(ServerBinder,继承自Binder并实现onTransact方法)之间的字符串传递,透彻理解Binder通信的运作原理。 项目框架中,vrp pso 源码服务端在Service的onBind方法中返回一个ServerBinder实例。对比手动实现与AIDL生成的代码,AIDL的便捷性便一目了然。客户端通过ServiceConnection,如下面这段代码,与远程服务建立连接:1. 创建ServiceConnection,获取远程服务的IBinder
2. intent设置服务类名:"com.binder.server.RemoteService"
3. bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
4. 若未连接,尝试bindService
5. 传递数据:通过IBinder调用mStingEditText的文本,如data.writeString(text)
6. 成功连接后,调用transact方法传递请求
接收数据的环节,服务端将数据展示在tvShowMessage上,通过新线程处理,如`new Handler().post(() -> ServerMainActivity.tvShowMessage.setText(message));`。当连接断开时,serviceConnection的onServiceDisconnected方法会被触发。 关键在于客户端如何通过IBinder获取服务端对象并调用transact进行跨进程通信。AIDL的引入让这个过程更加优雅,例如在ClientMainActivityUseAidl中,服务连接成功后,通过IBinder代理mServer,看源码痛苦调用自定义接口IShowMessageAidlInterface的showMessage方法。 在交互过程中,客户端通过IShowMessageAidlInterface的Stub内部类,将本地的IBinder转换为接口,这样数据的发送就通过showMessage方法进行。AIDL的asInterface方法负责封装本地或远程处理,Proxy类则负责数据的打包和跨进程传输,确保数据的无缝传递。 总结来说,客户端利用AIDL的asInterface处理远程IBinder,而Proxy类则是这一切的幕后功臣。服务端的onBind方法返回AIDL生成的Stub,它在客户端调用transact时负责接收和处理请求,执行showMessage方法。这样,AIDL生成的Stub和Proxy成为客户端发送数据的桥梁,而在服务端,它们则是数据处理的核心所在。 掌握Binder机制和AIDL的精髓,你将解锁Android进程间通信的元素之刃源码无尽可能,为你的应用开发增添无限力量。无论何时,当你深入探索Android源码,这些核心原理都将是你不可或缺的指南。AndroidFramework ä¹å¯å¨ ServiceManager
æ¬ææºç åºäº Android ï¼æ¶åç¸å ³æºç å¦ä¸ãServiceManagaer æ¯ Binder çå®æ¤è¿ç¨ï¼å¨ Binder æºå¶ä¸èµ·çéè¦çä½ç¨ãæ¬æå°ä»æºç çè§åº¦å¯¹å ¶è¿è¡åæï¼æ´ä½æµç¨å¦ä¸ï¼
æ¶åºå¾å¦ä¸ã
å æ¥çç ServiceManager æ¯å¦ä½å¯å¨çï¼
å¨ Zygote ä¸æä¸è¯´è¿ï¼ init è¿ç¨å¯å¨ç第äºé¶æ®µä¼è§£æ init.rc æ件ã
å¨è¿ä¹åä¼è§¦å trigger init ã
ç»å init.rc çç action init åäºä»ä¹ã
å½è§¦å trigger init åï¼ä¼å¯å¨ servicemanager æå¡ï¼å ¶å£°æå¦ä¸ã
对åºçæ§è¡æ件为 /system/bin/servicemanager ï¼å¨ç¼è¯åä½äº frameworks/native/cmds/servicemanager ä¸ï¼æ¥çç Android.bp ã
å ¶å¯¹åºçæºç 为 service_manager.c å binder.c ï¼å ¥å£å½æ° main() ä½äº servicemanager.c ã
å¯å¨å® ServiceManager åä¼æå¼ Binder 驱å¨ã
å¨ main() ä¸é¦å è°ç¨ binder_open() ã
binder_open() 主è¦åäºå¦ä¸äºæ ï¼
ç»ç»æä½ binder_state åé å åã
ç³»ç»è°ç¨ open() æå¼ /dev/binder ï¼å¦ææå¼é©±å¨å¤±è´¥ï¼åæ§è¡ fail_open éæ¾å åã
ç®åç解éä¸ä¸ä»ä¹æ¯ç³»ç»è°ç¨ï¼
ç±äºéè¦éå¶ä¸åçç¨åºä¹é´ç访é®è½åï¼é²æ¢ç¨åºè·åå«çç¨åºçå åæ°æ®ï¼ CPU åååºä¸¤ä¸ªæéç级ï¼ç¨æ·æå å æ ¸æã
ææçç¨æ·ç¨åºé½æ¯è¿è¡å¨ç¨æ·æï¼ä½ææ¶éè¦åä¸äºå æ ¸æçäºæ ï¼èå¯ä¸å¯ä»¥åè¿äºäºæ çå°±æ¯æä½ç³»ç»ï¼æ以ç¨åºéè¦åæä½ç³»ç»å起请æ±ï¼ä»¥ç¨åºçååæ¥æ§è¡è¿äºæä½ãè¿æ¶å°±éè¦ä¸ä¸ªä»ç¨æ·æåæ¢å°å æ ¸æä½ä¸è½æ§å¶å æ ¸æä¸æ§è¡çæºå¶ï¼è¿ç§æºå¶å°±æ¯ ç³»ç»è°ç¨ã
ç³»ç»è°ç¨ ioctl() ä¼ å ¥ BINDER_VERSION å½ä»¤è·å Binder 驱å¨çæ¬ï¼å¯¹æ¯çæ¬æ¯å¦ä¸è´ï¼ä¸ä¸è´åæ§è¡ fail_open éæ¾å åã
ç³»ç»è°ç¨ mmap() æ å° kb çå å空é´ï¼å³æ Binder 驱å¨æ件ç kb æ å°å°å å空é´ä¾ ServiceManager 使ç¨ï¼å åæ å°å¤±è´¥åæ§è¡ fail_map ï¼å ³é fd 并éæ¾å åã
ServiceManager è¿ç¨ mmap çå å大å°å¯ä»¥éè¿ adb shell å½ä»¤æ¥çã
å¯ä»¥çå°å åæ å°å°å为 0xff ~ 0xf ï¼å·®ä¸º 0x å³åè¿å¶ç kb ã
æå¼ Binder 驱å¨åä¼å° ServiceManager 设置为ä¸ä¸æ管çè ã
è°ç¨ binder_become_context_manager() ã
android æ°å¢ BINDER_SET_CONTEXT_MGR_EXT å½ä»¤æ¥è®¾ç½®å®å ¨çä¸ä¸æ管çè ï¼å¦æ设置失败ï¼å使ç¨åæç BINDER_SET_CONTEXT_MGR å½ä»¤æ¥è®¾ç½®ä¸ä¸æ管çè ï¼ä¸¤è åºå«å¨äºæ¯å¦æºå¸¦åæ°ã
æåä¼è¿å ¥å¾ªç¯ï¼ä» Binder 驱å¨è¯»åå解ææ°æ®ã
è°ç¨ binder_loop() è¿å ¥å¾ªç¯ï¼ä¸æå°éè¿ç³»ç»è°ç¨ ioctl() ä» Binder 驱å¨è¯»åæ°æ®ï¼å¹¶éè¿ binder_parse() è¿è¡æ°æ®è§£æã
注æè¿éè°ç¨ binder_loop() ä¼ å ¥ç svcmgr_handler() ï¼åé¢ä¼ä½¿ç¨å°ã
binder_write() ä¼å°è£ struct binder_write_read ï¼å¹¶éè¿ç³»ç»è°ç¨ ioctl() å°å¯¹åºçå½ä»¤ä¼ éç» Binder 驱å¨ã
binder_parse() ç¨æ¥è§£æä» Binder 驱å¨è¯»åå°çæ°æ®ï¼ç¶åæ ¹æ®ä¸åçå½ä»¤æ§è¡å¯¹åºçæä½ã
å 为 cmd å½ä»¤å¯è½æå¤ä¸ªï¼æ以éè¿ while 循ç¯æ¯æ¬¡å¤çä¸ä¸ª cmd å½ä»¤ï¼å¤ cmd çç»æ大è´å¦ä¸å¾æ示ã
è¿ééç¹çä¸ BR_TRANSACTION å½ä»¤ã
BR_TRANSACTION æ¯ Binder 驱å¨å Server 端åé请æ±æ°æ®ã
binder_transaction_data çç»æå¦ä¸ï¼å ¶è¡¨æäº transcation ä¼ è¾çå ·ä½è¯ä¹ï¼è¯ä¹ç è®°å½å¨ code ä¸ï¼ä¸åè¯ä¹ç æºå¸¦çæ°æ®æ¯ä¸åçï¼è¿äºæ°æ®ç± data æå®ã
å¨è§£æå® binder_transaction_data çå ·ä½è¯ä¹åï¼ä¼è°ç¨åé¢ä¼ ç» binder_loop() ç svcmgr_handler() ï¼å ¶å®å°±æ¯ switch case è¯ä¹ç åä¸åçäºæ ã
ServiceManager çåè½å ¶å®å¾ç®åï¼
è³æ¤ ServiceManager å°±åæå®äºã
log4j2(ä¸) è·å ILoggerFactory
å ³äºlog4j2çåå§åæµç¨ï¼ç°å¨é¡¹ç®åºæ¬é½æ¯springboot项ç®ï¼å°±éè¦ç»å springboot æºç æ¥è§£æï¼è¿åå¯ä»¥åè Springboot - Log4J2LoggingSystemæºç 解æ
å 为spring-boot-starterä¾èµä¸æ¥å¿ä½¿ç¨çæ¯spring-boot-starter-loggingï¼è¿éé¢æ¯ç¨çæ¯logbackï¼æ以éè¦å åé¤æ¤ä¾èµ
åæ·»å log4j2ä¾èµ
å¦ææ们æ³ä½¿ç¨ yml åç¼çé ç½®æ件è¿éè¦åå ä¸ä¸ªä¾èµ
ç¶åç¸å ³ä¾èµçæ¬å¦ä¸
以ä¸æºç åºäº log4j 2.7ã
å çä¸å¼ log4jå®æ¹æä¾çç±»å¾
å ç®åäºè§£ä¸ä¸è¿äºç±»
è¿æ»¤å¨çç§ç±»ä¹å¾å¤ï¼æ¯å¦æ ¹æ®æ¥å¿çº§å«ãFilterä¼è¿åä¸ä¸ªæ举å¼Filter.Resultï¼æä¸ç§ï¼
详ç»åè§ log4j - Filters
log4jçåå§åæµç¨å®å¨æç¹é¥¶ï¼è¿éç®è¦è®²è®²ã
LoggerFactory#getLogger(String)
å¨åªæä¸ä¸ªlog4j2çä¾èµæ¶ï¼å è½½æµç¨å¤§è´å¦ä¸ï¼
å¨ getILoggerFactory() æ¹æ³ä¸åäºè¿ä¹å 件äº
åçä¸ log4j2 ç StaticLoggerBinder æºç
ä¸ä¸ç¯ççåç»Loggerçè·åã
æ·»å logback ä¾èµï¼ç´æ¥æ¾å¼ spring-boot-starter-logging ä¹è¡ï¼ï¼è¿æ ·æ们项ç®å°±æ两个 org/slf4j/impl/StaticLoggerBinder.class äº
ç¶åå¯å¨ï¼æ示
æççé®å°±æ¯ä¸ºå¥ä¸ç¨log4j2èç¨logbackï¼å°±æå¼è¿ä¸ªç½åæ¥äºä¸ï¼éé¢æåæä¸æ®µ
åè¯æ们
好å§ï¼éæºçæä¹æ¯éäºãã
åè
_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv*env,jobjectclazz){ //gCurRuntime是个全局的变量,后面跟上的是另外实现的方法。gCurRuntime->onZygoteInit();}onZygoteInit源码分析
onZygoteInit函数在需要源码的位置:/frameworks/base/cmds/app_process/app_main.cpp文件中。
该函数是个虚函数,并且是一个无返回值和无参数的函数virtualvoidonZygoteInit(){ //Re-enabletracingnowthatwe'renolongerinZygote.atrace_set_tracing_enabled(true);//获取进程的状态信息sp<ProcessState>proc=ProcessState::self();//打印日志信息ALOGV("Appprocess:startingthreadpool.\n");//启动线程池proc->startThreadPool();}startThreadPool源码分析startThreadPool系统实现在\frameworks\native\libs\binder\ProcessState.cpp文件中。
每一个支持Binder进程间通信机制的进程内都有一个唯一的ProcessState对象,当这个ProcessState对象的成员函数StartThreadPool函数被第一次调用的时候,它就会在当前进程中启动一个线程池,并将mThreadPoolStarted这个成员变量设置为true。
//该函数是个无参数,无返回值的函数voidProcessState::startThreadPool(){ AutoMutex_l(mLock);//判断线程池是否启动状态,启动的话就将标志信息设置为true属性。if(!mThreadPoolStarted){ mThreadPoolStarted=true;spawnPooledThread(true);}}总结Binder在android底层中是一个非常重要的机制,我们在实际的项目调用过程中,我们在app应用程序中只要实现自己的Binder本地对象的时候,跟其他服务一样,unity demo源码只需要将它进行启动起来,并且进行注册到ServerMananger就可以了。至于内部的实现一般是不需要去关心的。
Android Binder Hookçå®ç°
Binder Hookå¯ä»¥Hookæå½åAppç¨å°çç³»ç»Serviceæå¡ã以LocationManager为ä¾ï¼å¨è·åä¸ä¸ªLocationManageræ¶å为两æ¥ã第ä¸ï¼è·åIBinder对象ï¼ç¬¬äºï¼IBinder对象éè¿asInterface()转å为LocationMangerService对象ãæååå§åLocationManagerï¼applicationå±ç¨å°çé½æ¯LocationManagerã
Hookç大è´åçæ¯ï¼ServiceManagerå¨è·åæ个Binderæ¶ï¼å¦ææ¬å°æç¼åçBinderï¼å°±ä¸åè·¨è¿ç¨è¯·æ±Binderäºãæ们å¯ä»¥å¨ç¼åä¸å å ¥èªå·±çBinderï¼ä½¿å¾ServiceManageræ¥è¯¢æ¬å°ç¼åæ¶å¾å°ä¸ä¸ªèªå®ä¹çCustomBinder对象ï¼ä¸åè·¨è¿ç¨åç³»ç»è¯·æ±ã并ä¸ILocationManager.Stub.asInterface(CustomBinder)æ¹æ³è¿åæ们èªå®ä¹çService对象ã
è¿éé¢æ两个å°æ¹éè¦ç¨å°èªå®ä¹ç对象ãç±äºæ们åªHookå ¶ä¸ä¸é¨åçåè½ï¼å ¶ä»åè½è¿éè¦ä¿çï¼æ以ç¨å¨æ代ççæ¹å¼å建èªå®ä¹çBinderåèªå®ä¹çServiceã
å¨ç解åé¢çå 容åä½ éè¦äºè§£è¿äºç¥è¯ç¹ï¼
Activityçç±»å¨è·åç³»ç»Serviceæ¶ï¼é½æ¯è°ç¨getSystemService(serviceName)æ¹æ³è·åçã
Context ç getSystemService() æ¹æ³è°ç¨äº SystemServiceRegistry ç getSystemService() æ¹æ³ã
SystemServiceRegistry ä¸æä¸ä¸ªå¸¸é SYSTEM_SERVICE_FETCHERSï¼è¿æ¯ä¸ä¸ªMapãä¿åäºServiceNameå对åºçServiceFetcherãServicFetcheræ¯ç¨äºåå»ºå ·ä½Serviceçç±»ãServiceFetcher çå ³é®æ¹æ³æ¯ createService() æ¹æ³ã
å¨ ServiceFetcher ç createService() æ¹æ³ä¸ï¼è°ç¨äº ServiceManager.getService(name) æ¹æ³ã以 LocationManager 对åºç ServiceFetcher 为ä¾ï¼å®çcreateService()æ¹æ³æºç å¦ä¸ï¼
åå¦æ们è¦ä¿®æ¹ LocationManager ç getLastKnownLocation() æ¹æ³ï¼ä¸æé½æ¯ï¼ãæ们è¦åçå°±æ¯è®©ServiceManager.getService("location")è¿åæ们èªå®ä¹çBinderãå çä¸ä¸è¿ä¸ªæ¹æ³ç®ååçæºç ï¼
sCacheæ¯ä¸ä¸ªMapï¼ç¼åäºå·²ç»åç³»ç»è¯·æ±è¿çBinderãå¦ææ们éè¦è®©è¿ä¸ªæ¹æ³è¿åæ们æ们èªå·±çbinderï¼åªéè¦äºå å¾sCacheä¸putä¸ä¸ªèªå®ä¹çBinderå°±è¡äºã
å¨putä¹åï¼éè¦å å建åºä¸ä¸ªèªå®ä¹çBinderãè¿ä¸ªBinderå¨è¢« ILocationManager.Stub.asInterface å¤çåï¼å¯ä»¥è¿åä¸ä¸ªèªå®ä¹ç LocationManagerServiceã
å çä¸ä¸Binderç asInterface() çå®ç°ï¼
å¦ææ queryLocalInterface()æ¹æ³è¿åä¸ä¸ªèªå®ä¹çServiceï¼ä½¿å¾èµ°ifè¯å¥å é¨ï¼ä¸èµ°elseï¼é£å°±ç®æ¯Hookæåäºã
å设æ们æ³è®©ç³»ç»çLocationManagerè¿åçä½ç½®ä¿¡æ¯å ¨æ¯å¨å¤©å®é¨(., .)ãé£æ们éè¦ä½¿å¾ LocatitionManagerService ç getLastLocation() æ¹æ³ è¿åçå ¨æ¯ (., .)ã
ç±äºæ们ä¸è½ç´æ¥æ¿å°ç³»ç»çè¿ä¸ªService对象ï¼å¯ä»¥å ç¨åå°çæ¹å¼æ¿å°ç³»ç»çLocationManagerServiceãç¶åæ¦æªgetLastLocation()æ¹æ³ã
åççBinder对象å¨è°ç¨ queryLocalInterface() æ¹æ³æ¶ä¼è¿ååççService对象ãæ们å¸æè¿å3.1ä¸çèªå®ä¹Serviceãæ以è¿éæ¦æª queryLocalInterface() æ¹æ³ã
æäºèªå®ä¹çBinderåï¼å°å®æ³¨å ¥å°ServiceMangerçsCacheåéä¸å°±å®æHookäº~
å½onClick被è°ç¨çæ¶åï¼ToaståLogé½ä¼æ¾ç¤ºå¤©å®é¨çåæ (., .)ãè¯æHookæåï¼
ä½ çè³å¯ä»¥ç¨Binder Hookçæ¹å¼Hookæ ActivityManagerã
androidåLinuxçåºå«ï¼
æ以ä¸ä¸ç¹åºå«ï¼1ãAndroid没ææ¬å°çªå£ç³»ç»ï¼èLinuxæ¯æXçªå£ç³»ç»ã
2ãAndroid没æglibcæ¯æï¼èLinuxæ¯æglibcæ¯æçã
3ãAndroidæ¯æèªå·±ä¸æç驱å¨ç¨åºã
è½ç¶AndroidåºäºLinuxå æ ¸ï¼ä½æ¯å®ä¸Linuxä¹é´è¿æ¯æå¾å¤§çå·®å«ã
æ©å±èµæ
Androidä¸æç驱å¨ç¨åº
1ãAndroid Binder åºäºOpenBinderæ¡æ¶çä¸ä¸ªé©±å¨ï¼ç¨äºæä¾ Androidå¹³å°çè¿ç¨é´éä¿¡(InterProcess Communicationï¼IPC)åè½ãæºä»£ç ä½äºdrivers/staging/android/binder.cã
2ãAndroidçµæºç®¡ç(PM) ä¸ä¸ªåºäºæ åLinuxçµæºç®¡çç³»ç»çè½»é级Androidçµæºç®¡ç驱å¨ï¼é对åµå ¥å¼è®¾å¤åäºå¾å¤ä¼åãæºä»£ç ä½äºï¼
kernel/power/earlysuspend.c
kernel/power/consoleearlysuspend.c
kernel/power/fbearlysuspend.c
kernel/power/wakelock.c
kernel/power/userwakelock.c
3ãä½å å管çå¨(Low Memory Killer) æ¯Linuxçæ åçOOM(Out Of Memory)æºå¶æ´å çµæ´»ï¼å®å¯ä»¥æ ¹æ®éè¦ææ»è¿ç¨ä»¥éæ¾éè¦çå åãæºä»£ç ä½äº drivers/staging/ android/lowmemorykiller.cã
4ãå¿åå ±äº«å å(Ashmem) 为è¿ç¨é´æä¾å¤§åå ±äº«å åï¼åæ¶ä¸ºå æ ¸æä¾åæ¶å管çè¿ä¸ªå åçæºå¶ãæºä»£ç ä½äºmm/ashmem.cã
5ãAndroid PMEM(Physical) PMEMç¨äºåç¨æ·ç©ºé´æä¾è¿ç»çç©çå ååºåï¼DSPåæäºè®¾å¤åªè½å·¥ä½å¨è¿ç»çç©çå åä¸ãæºä»£ç ä½äºdrivers/misc/pmem.cã
6ãAndroid Logger ä¸ä¸ªè½»é级çæ¥å¿è®¾å¤ï¼ç¨äºæåAndroidç³»ç»çåç§æ¥å¿ãæºä»£ç ä½äºdrivers/staging/android/logger.cã
7ãAndroid Alarm æä¾äºä¸ä¸ªå®æ¶å¨ï¼ç¨äºæ设å¤ä»ç¡ç ç¶æå¤éï¼åæ¶å®è¿æä¾äºä¸ä¸ªå³ä½¿å¨è®¾å¤ç¡ç æ¶ä¹ä¼è¿è¡çæ¶éåºåãæºä»£ç ä½äºdrivers/rtc/alarm.cã
8ãUSB Gadgeté©±å¨ ä¸ä¸ªåºäºæ å Linux USB gadget驱å¨æ¡æ¶ç设å¤é©±å¨ï¼AndroidçUSB驱å¨æ¯åºäºgaegetæ¡æ¶çãæºä»£ç ä½äºdrivers/usb/gadget/ã
9ãAndroid Ram Console 为äºæä¾è°è¯åè½ï¼Androidå 许å°è°è¯æ¥å¿ä¿¡æ¯åå ¥ä¸ä¸ªè¢«ç§°ä¸ºRAM Consoleç设å¤éï¼å®æ¯ä¸ä¸ªåºäºRAMçBufferãæºä»£ç ä½äºdrivers/staging/android / ram_console.cã
ãAndroid timed device æä¾äºå¯¹è®¾å¤è¿è¡å®æ¶æ§å¶çåè½ï¼ç®åæ¯ævibratoråLED设å¤ãæºä»£ç ä½äºdrivers/staging/android /timed_output.c(timed_gpio.c)ã
åèèµæï¼ç¾åº¦ç¾ç§ââAndroid
ç¾åº¦ç¾ç§ââlinux
面试 | 再也不怕被问 Binder 机制了
Binder机制是Android特有的进程间通信(IPC)方式,它基于C/S架构,由运行在用户空间的Client、Server、Service Manager组件,以及运行在内核空间的Binder驱动组成。完整过程包括:通过内存映射技术减少数据拷贝次数,发送方进程也做内存映射可以实现数据0拷贝传输,但考虑到性能和复杂性,Binder方式更适合Android。
mmap内存映射原理是在进程的用户空间和内核空间之间建立映射关系,实现文件磁盘地址与进程虚拟地址空间中的虚拟地址一一对映,使得进程可以采用指针方式读写操作内存,系统自动回写脏页面到磁盘,完成文件操作而无需再调用read、write等系统调用函数。同时,内核空间对这段区域的修改直接反映用户空间,实现不同进程间的文件共享。
在进程间通信(IPC)场景下使用mmap时,通常只需要在进程的用户空间和内核空间之间建立映射关系,不一定需要映射到外部存储介质,除非希望将共享内存内容持久化到磁盘上。
当使用匿名内存映射进行进程间通信时,创建一段内核空间内存并在进程的用户空间与之建立映射关系,允许多个进程共享同一段内核空间内存,实现数据共享和同步。匿名内存映射不与任何文件关联,仅在进程间实现高效数据传输。
在使用mmap进行进程间通信时,创建匿名内存映射,不映射到外部存储介质,仅在用户空间与内核空间之间建立映射关系。这允许多个进程共享内核空间内存,提高数据访问效率和性能。
在实际应用中,使用带有回调接口(Callback)的方法参数调用服务端进程提供的方法时,方法调用线程和回调线程是否相同取决于服务端实现。通常服务端采用异步处理方式,将请求放入队列或线程池中处理,调用回调接口,线程可能不相同。
对于oneway接口调用,即使服务端立即在当前线程中处理请求并调用回调接口,客户端的调用也不会阻塞。oneway调用是单向异步的,客户端调用后立即返回,不会等待服务端响应。
Intent传递参数在同一个进程中的两个Activity间,由于涉及Binder IPC通信,Intent数据携带大小会受到Binder事务大小限制。通常限制在1MB左右,超过限制会抛出异常。解决方法包括优化数据结构、使用事件总线或回调接口传递大对象。
为了深入理解Android框架,可参考《Android Framework核心知识点》手册,内容涵盖Init、Zygote、SystemServer、Binder、Handler、AMS、PMS、Launcher等知识点,以及相关源码分析资料,帮助快速掌握Android框架核心。
Framework层的Binder(源码分析篇)
本文以android-.0.0_r的AOSP分支为基础,解析framework层的Binder工作原理。
从ServiceManager的getService方法入手,其核心代码是通过getIServiceManager().getService(name)获取服务。首先,ServiceManager的实现与进程中的ProcessState密切相关,ProcessState是单例,负责打开和映射Binder驱动。构造函数中,它会初始化驱动、验证版本并设置线程数,接着进行binder映射。
在ProcessState的getContextObject方法中,调用native函数android_util_Binder.cpp中的getContextObject()。这个函数通过handle 0(ServiceManager的handle)获取BpBinder对象,然后通过javaObjectForIBinder函数将其转换为Java中的类型。
进一步分析,BpBinder与java层的Binder之间存在对应关系,通过BinderProxy NativeData创建单例的BinderProxy。然后,每个服务的BinderProxy实例化和计数处理都在这个过程中完成。ServiceManagerNative.asInterface方法简化了getIServiceManager的调用,通过调用asInterface实例化ServiceManagerProxy。
IServiceManager接口通过AIDL生成,其代理类ServiceManagerProxy实际上是不必要的。aidl文件在编译时生成对应java代码,用于binder通信。通过aidl文件,我们可以看到如queryLocalInterface等方法的实现细节。
在Parcel的协助下,客户端与服务端进行数据传递,通过序列化和反序列化进行交互。在transact函数中,对Parcel大小进行检查,避免数据传输过大导致的问题。最后,客户端与binder驱动的通信过程涉及了Transaction数据的写入、等待响应、数据处理和内存回收等步骤。
总的来说,framework层的Binder工作涉及服务管理、数据转换、通信协议和内存管理等环节,理解这些有助于深入掌握Binder的工作机制。