Android系统使用进程有什么优点?
1个App采用多进程实现的优点?
1个App使用多进程的原因:
虚拟机分配给每个进程的资源是有限的,LMK(Low Memory Killer)优先回收系统资源占用多的进程.
查看微信App运行了几个进程的命令:
adb shell ps -A |grep tencent
查询结果:
HWLLD-H:/ $ ps -A |grep tencent
u0_a121 12781 545 27892876 436924 0 0 S com.tencent.mm
u0_a121 13092 545 5677120 106016 0 0 S com.tencent.mm:push
u0_a121 13285 545 238093944 234700 0 0 S com.tencent.mm:appbrand0
u0_a121 13299 545 10023996 152260 0 0 S com.tencent.mm:appbrand1
u0_a121 14284 545 22470288 113608 0 0 S com.tencent.mm:xweb_privileged_process_0
u0_i22 14297 545 21911432 249268 0 0 S com.tencent.mm:xweb_sandboxed_process_0
App使用多进程的优点:
Binder是什么呢?
在android中我们所使用的Activity、Service等组件都需要和AMS(SystemServer进程中的一个服务AMS)通信,这种跨进程的通信都是通过Binder完成.
为什么要学习Binder?
跨进程通信IPC有哪些实现方案?
跨进程通信都要通过内核空间,才能实现进程间的通信
内存在操作系统中的划分
Binder是如何管理的?
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//启动引导程序(辅助程序)服务,
//如:ATMS(ActivityTaskManagerService)、PowerManagerService、SystemServiceManager等
//ActivityManagerService 在这里初始化
//mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
startBootstrapServices(t);
//启动核心服务,比如:电池服务、
startCoreServices(t);
//启动一些别的服务,比如:闹钟服务
startOtherServices(t);
ServiceManager.addService(String name, IBinder service)
方法,将服务添加到ServiceManager中去.Binder驱动是什么时候创建的?
进程在创建的同时就会创建Binder
驱动,这里我们拿ServiceManager
进程创建过程举例:
入口:
系统源码中,servicemanager
路径下的main.cpp
文件中,main
函数中会在ServiceManager
进程创建时,做一些初始化操作:
ProcessState::initWithDriver(driver)
方法初始化Binder
驱动,并在ProcessState
中将驱动打开open_driver(driver)
;ServiceManager
,代码如下:sp manager = new ServiceManager(std::make_unique());
Looper
对象并执行loop
轮询,代码如下:sp looper = Looper::prepare(false /*allowNonCallbacks*/);
Looper
一直轮询:looper->pollAll(-1);
总结:
Binder驱动是在Zygote进程创建后创建的,每一个进程创建的同时都会创建Binder驱动,用于与别的进程实现跨进程通信.
在Zygote进程初始化的时候,会在ZygoteInit
的main()
函数中创建一个Soket通信Server服务器ZygoteServer
,通过一个while
死循环轮询否有AMS
发送过来的消息,接收到消息则会通过fork()
创建一个进程,代码如下:
Zygote.forkAndSpecialize(...)
进程创建完成,接下来会走到native
层的文件中去打开Binder
驱动,流程如下:
ZygoteInit.main
()
->zygoteServer.runSelectLoop
(abiList)
->(ZygoteConnection)connection.processOneCommand
(this)
->handleChildProc
(…)
->ZygoteInit.zygoteInit
()
->ZygoteInit.nativeZygoteInit
();
这个ZygoteInit.nativeZygoteInit
本地方法最终会在AndroidRuntime.cpp
中注册,最终在app_main.cpp
文件中onZygoteInit()
方法中调用,该方法中会调用ProcessState::self()
,这个方法中会创建一个ProcessState
,这里面就包含了打开驱动的业务逻辑open_driver(driver)
.
Service的启动方式
Service是四大组件之一,使用的时候需要像Activity一样在清单文件中注册
AIDL (Android Interface Define Language/安卓接口定义语言)
Client
端和Server
端通过AIDL
实现进程间通信,Client
端和Server
端都需要创建.aidl
文件,同时这个文件的类名和包名都必须相同,这个.aidl
文件可以编译成Java
文件(还可以可以通过命令生成c++
文件),我们通过Java
文件就可以实现进程间通信,这个由.aidl
文件生成的Java
文件中,包含了内部类Stub
,而Stub
包含了子类Proxy
,Stub
类继承自Binder
,而Binder
实现了IBinder
,所以我们在Client
端在绑定Server
端的服务,在ServiceConnection
的回调方法中,可以拿到Server
端返回的IBinder
对象,然后在Client
端通过对IBinder
对象进行转换后就可以和Server
端进程通信.
实现步骤:
IAidl iAidl = IAidl.Stub.asInterface(service);// proxy
bindService流程分析
bindService()
@ContextWrapperbindService()
@ContextImpl
Activity
的超类Context
的实现类ContextImpl
的绑定服务方法bindServiceCommon()
ActivityManager.getService().bindIsolatedService(...)
//ActivityManager.java
public static IActivityManager getService() {
//这里的get()方法最终会调用Singleton中的create()方法,
//创建一个Proxy代理对象
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//根据名称获取到ServiceManager列表中存储的AMS的IBinder对象
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//将IBinder对象通过按照AIDL生成的Java类中的代理Proxy方式,
//通过Interface的Stub类的asInterface方法,
//将IBinder对象转换成Proxy对象,
//通过Proxy对象就可以调用Interface中的方法,
//从而实现跨进程通信
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
bindIsolatedService()
@ActivityManagerService
bindServiceLocked()
@ActiveServices
c.conn.connected(s.name, b.intent.binder, false);
requestServiceBindingLocked()
r.app.thread.scheduleBindService()
r
:是ServiceRecord,app
:是ProcessRecord,thread
:是IApplicationThread,他的实现类是ActivityThread.ApplicationThread;但是最终传递进来的thread对象其实是ActivityThread,所以我们查看ActivityThread中的scheduleBindService方法private void attach(boolean system, long startSeq) {
//省略无关代码...
//这里的ActivityManager.getService()返回是AMS
final IActivityManager mgr = ActivityManager.getService();
//所以最终调用AMS的attachApplication方法,将ApplicaitonThread的IBinder对象绑定到AMS
mgr.attachApplication(mAppThread, startSeq);
}
scheduleBindService()
@ActivityThread
handleBindService
@ActivityThread
在我们自定义Service的生命周期方法onBind()中,将创建的Stub类的对象传入作为返回值,构建出IBinder对象
publishService()
@ActivityManagerServicepublishServiceLocked()
@ActiveServicesc.conn.connected(r.name, service, false);
@ActiveServices
LoadedApk.ServiceDispatcher.InnerConnection.connected()
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
LoadedApk.ServiceDispatcher.connected()
doConnected()
@LoadedApk.ServiceDispatcher
onServiceConnected(name, service);
//服务已连接onServiceDisconnected(name);
//服务断开总结:
进程间通信Native层逻辑
ActivityManager.getService()
Binder.allowBlocking(rawGetService(name))
rawGetService()
IBinder binder = getIServiceManager().getService(name);
ServiceManagerProxy.getService()
IServiceManager.Stub.Proxy.getService()
(IBinder)mRemote.transact()
BinderProxy.transact()
transactNative
public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException
android_os_BinderProxy_transact()
@android_util_Binder.cpp
Parcel * parcel = parcelForJavaObject(env, dataObj);
transact()
@BpBinder.cppIPCThreadState::transact()
writeTransactionData()
@IPCThreadState.cpp
waitForResponse()
@IPCThreadState.cpp
talkWithDriver()
@IPCThreadState.cppioctl()
Binder驱动设备
总结:
ServiceManagerProxy(Java层)->BinderProxy(Framework层)->BpBinder(Native层)->ioctl->Binder驱动(Linux内核层)
这里我们将ServiceManager作为一个BBinder的实现类来研究,因为ServiceManager的超类的BBinder
main()
@servicemanager/main.cpp
BinderCallback::setupTo(looper);
@servicemanager/main.cpp
handleEvent()
方法中进行消息处理;handleEvent()
@servicemanager/main.cpp BinderCallBackhandlePolledCommands()
; //一直轮询,直至获取到消息,并处理消息
do {
result = getAndExecuteCommand();//获取到消息,则执行命令
} while (mIn.dataPosition() < mIn.dataSize());
executeCommand(cmd);
transact()
@IPCThreadState.cpp
BBinder.transact()
@Binder.cppBBinder.onTransact()
@Binder.cpp
onTransact()
@BnServiceManager.cpp
android::binder::Status _aidl_status(getService(in_name, &aidl_return));
//举例,这里用getService方法对应的case代码举例getService()
@ServiceManager
总结:
Binder驱动通过ioctl将消息发送出来 -> BBinder通过Loop轮询Binder驱动发送来的消息并处理 -> 交给BnServiceManager的onTransact()方法处理 -> 最终通过ServiceManager.getService方法获取IBinder对象
Server端ServiceManager是什么?
ServiceManager是一个Native层的进程,由init进程创建,早于zygote进程启动.
ServiceManager进程启动做了三件事情:
sp ps = ProcessState::initWithDriver(driver);
BBinder
对象
sp manager = new ServiceManager(std::make_unique());
//实例化ServiceManager构建成BBinder对象,因为ServiceManager的超类的BBinderIPCThreadState::self()->setTheContextObject(manager);
//将BBinder对象设置到线程中BinderCallback::setupTo(looper);
//Binder发送消息给ServiceManager/BBinder,ServiceManager/BBinder监听Binder驱动发送过来的消息
class BinderCallback : public LooperCallback {
public:
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
...代码省略
}
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
//从Binder驱动接收到消息并处理
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
};
ClientCallbackCallback::setupTo(looper, manager);
//在Looper循环中监听Binder驱动发送来的消息ServiceManager父类之间的关系:
一个Service类中实现了.Stub类,Stub类继承自Binder类,Binder类实现了IBinder接口,我们就可以将他当作是一个Server服务端,用于提供给客户端Client使用.