Android Service进程间通信
介绍进程通信
进程间的通信可以理解为一个app向另一个app发出请求、响应请求的过程,举个例子,比如你定了一个外卖,此时需要向商家付款,系统会为你提供很多付款方式:支付宝、微信、银行卡等等,你选择了微信,系统就会为你打开微信进行支付。这就是一种进程通信
服务端和客户端
没有明确的服务端与客户端,只要是提供服务的都可以理解为服务端,只要是请求服务的都可以理解成客户端,没有绝对的服务端,客户端。
AIDL
这里里我们把客户端和服务器理解为一个中国人和一个美国人,他们语言不同但是他们又需要交流完成任务,此时需要一个能让双方理解对方意图的工具,这就是AIDL
介绍
AIDL,全称是Android Interface Define Language,即安卓接口定义语言,可以实现安卓设备中进程之间的通信(Inter Process Communication, IPC)。安卓中的服务分为2类:本地服务(网络下载大文件,音乐播放器,后台初始化数据库的操作);远程服务(远程调用支付宝进程的服务。。)
使用AIDL
创建服务端moudle:aidl_server
1、将as切换到Project下,按照如图所示创建文件夹命名为aidl,在aidl文件夹下创建aidl文件,命名为IMyAidlInterface.aidl
2、修改aidl文件,提供一个方法,该方法 就是处理客户端的请求
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
这里我们通过服务器做一个加法运算
interface IMyAidlInterface {
int add(int a, int b);
}
3、rebuild project之后会发现自动生成一个Java文件:IMyAidlInterface.java
4、在服务端中新建一个类,继承Service,在其中定义一个IBinder类型的变量iBinder,引用上述接口IMyAidlInterface.java类中的Stub类对象,实现其中的add方法,在Service的onBind方法中,返回iBinder变量。最终代码如下:
public class MyService extends Service {
public MyService() {
}
//创建字典
Binder binder = new IMyAidlInterface.Stub() {
@Override
public int add(int a, int b) throws RemoteException {
return a+b;
}
};
//将服务与字典绑定
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
5、清单文件中注册SErverService服务,在注册时应设置exported属性为true,保证该Service能被其他应用调用,否则会报
java.lang.SecurityException: Not allowed to bind to service Intent 异常。
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.add"/>
</intent-filter>
</service>
恭喜你,服务器已经准备就绪!!
客户端moudle:aidl_client
1、在客户端创建同样AIDL文件,要求包名AIDL名字必须一致,内容也必须一样提供add方法,rebuild 项目
2、在Activity中写java代码:
public class MainActivity extends AppCompatActivity {
private Button send;
private ServiceConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//服务器包名,用来确定是哪个app
intent.setPackage("com.example.highday15");
//服务频道
intent.setAction("com.add");
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
int add = iMyAidlInterface.add(53, 74);
Toast.makeText(MainActivity.this, add + "", Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
bindService(intent,connection,BIND_AUTO_CREATE);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
}