在Android 框架层frameworks中常常会通过context.getSystemService()获取调用系统服务,本质是通过AIDL调用了系统服务。
以下转载一篇原理介绍:
[转载]
Android的跨进程通信
为什么不能直接跨进程通信?
为了安全考虑,应用之间的内存是无法互相访问的,各自的数据都存在于自身的内存区域内。
为了安全考虑,应用之间的内存是无法互相访问的,各自的数据都存在于自身的内存区域内。
如何跨进程通信?
要想跨进程通信,就要找到一个大家都能访问的地方,例如硬盘上的文件,多个进程都可以读写该文件,通过对该文件进行读写约定好的数据,来达到通信的目的。
Android中的跨进程通信采用的是Binder机制,其底层原理是共享内存。
Binder在linux层面属于一个驱动,但是这个驱动不是去驱动一个硬件,而且驱动一小段内存。
不同的应用通过对一块内存区域进行数据的读、写操作来达到通信的目的。
不同的应用在同一内存区域读写数据,为了告知其他应用如何理解写入的数据,就需要一个说明文件,这就是AIDL。当两个应用持有相同的AIDL文件,就能互相理解对方的的意图,就能做出相应的回应,达到通信的目的。
系统服务和应用端的通信机制
Binder对象都有各自的内存区域,当Binder1想要向Binder2发送数据时,就会把数据写入自己的内存区域,然后通知Binder驱动,Binder驱动会把数据拷贝到Binder2的内存区域,然后通知Binder2进行读取,Binder读取完毕后,将把数据写入binder2的内存区域,然后通知Binder驱动,Binder驱动将会把数据拷贝到Binder1的内存区域中。这样就完成了一次通信。
如果Binder1是系统服务,Binder2是系统服务的远程对象,这样任何应用程序在获取了Binder2的引用后,都可以和Binder1进行通信。但是缺点也很明显,只能由应用端请求系统服务,系统服务不能主动去联系应用端。WifiManagerService之类的就是采用这种方式。
还有一种方式是Binder1是系统服务,Binder2是应用端创建的Binder对象,他们两者通过Binder驱动进行连接后,应用端可以主动调系统服务,系统服务也可以主动调用应用端。WindowManagerService就是采用的这种方式。
还有一种方式是Binder1是系统服务,Binder2是应用端创建的Binder对象,他们两者通过Binder驱动进行连接后,应用端可以主动调系统服务,系统服务也可以主动调用应用端。WindowManagerService就是采用的这种方式。
另外,我们在应用层也可以通过AIDL提供服务给其它进程调用,以下是一个实例:
简单的服务绑定
public class MainActivity extends Activity implements ServiceInterface {
private Intent intent;
private ServiceInterface si;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {//意外中断事件
System.out.println("意外中断事件");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {// 监听器
si = (ServiceInterface) service;
System.out.println("绑定成功");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, MySercvice.class);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
// 绑定服务,得到IBinder(ServiceInterface的实现类)
bindService(intent, conn, BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
// 解绑服务
unbindService(conn);
System.out.println("解绑服务");
}
@Override
public void pay(View view) {
// 调用服务中pay方法
si.pay(view);
}
@Override
public void collection(View view) {
// 调用服务中的collection()方法
si.collection(view);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println("---------------onActivityResult------------------");
}
public interface ServiceInterface {
/**
* 付款
* @param view
*/
public void pay(View view);
/**
* 收款
* @param view
*/
public void collection(View view);
}
public class MySercvice extends Service {
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();//返回一个可以调用pay()和collection()的对象
}
class MyBinder extends Binder implements ServiceInterface{
@Override
public void pay(View view) {
System.out.println("支付宝付款");
}
@Override
public void collection(View view) {
System.out.println("支付宝收款");
}
}
}
复习使用aidl
创建一个单独的服务程序(单独的进程)
package com.example.remoteserver.invokeinterface;
interface InvokeInterface {
void pay();
void collection();
}
package com.example.remoteserver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import com.example.remoteserver.invokeinterface.InvokeInterface.Stub;
public class RemoteServer extends Service {
@Override
public IBinder onBind(Intent arg0) {
System.out.println("onBind");
return new MyBinder();
}
class MyBinder extends Stub {
@Override
public void pay() {
System.out.println("远程支付");
}
@Override
public void collection() {
System.out.println("远程收款");
}
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("onDestroy onDestroy");
}
}
RemoteActivity调用其他进程的方法
package com.example.remoteserver.invokeinterface;
interface InvokeInterface {
void pay();
void collection();
}
package com.example.remoteactivity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import com.example.remoteserver.invokeinterface.InvokeInterface;
import com.example.remoteserver.invokeinterface.InvokeInterface.Stub;
public class MainActivity extends Activity {
private Intent intent;
private InvokeInterface ik;
private ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {// 绑定成功
// ik=(InvokeInterface) service;
ik=Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent=new Intent("itheima.service.REMOTE_SERVICE");
}
@Override
protected void onResume() {
super.onResume();
bindService(intent, conn,Context.BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
unbindService(conn);//解绑服务
}
public void pay(View view){
// ik.pay();
try {
ik.pay();
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void collection(View view){
try {
ik.collection();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}