AIDL android 接口定义语言的使用 bindService
Ok,第一次写博客,主要是发现之前学过的知识差不多忘完了,一直没有做笔记的习惯。为了培养一个好习惯,发扬极客精神,写下此文鼓励一下自己。
废话不说,首先解释一下AIDL android接口定义语言是个什么鬼?降到AIDL不得不提一下IPC--> [进程间通讯](http://blog.csdn.net/coolmeme/article/details/6053418) Inter-Process Communication。在PC上两个独立的程序是怎么进行通信的?他们的通讯协议是什么?
OK,首先你得知道在安卓中 每一个应用程序都有自己独立的内存空间,所以互相之间的调用,通讯成为不可能,aidl的出现是解决互相调用的一种方式 他通过定义在两个应用程序定义相同的接口(表面上看,就像是在两个不能通信的地方之间打出两个洞,至于里面是怎么样打通的犹未可知)来实现通讯。
如果需要深入理解原理请绕道拜读[大神](http://www.open-open.com/lib/view/open1469493649028.html)的作品。
![生成AIDL文件](https://img-blog.csdn.net/20161110211348195)
值得注意的是android接口定义语言是没有权限修饰符的,加上实惠报错滴:
创建AIDL文件后,as会自动生成包路径:
接下来我们说说怎么通过远程接口来访问另一个进程的服务:
你当然要让你的Ibinder类继承接口的实现类Stub,这个类是自动生成的 放心大胆的继承吧
首先这是本地实现的代码:
public class PhoneListenerService extends Service {
public static String TAG = "PhoneListenerService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "反回binder对象");
return new MyBinder();
}
public void PalyMp3() {
Log.e("PhoneListenerService", "我是服务的方法 为您播放一段音乐");
}
private class MyBinder extends Binder implements IService {
public MyBinder() {
super();
}
public void Xisangna(){
Log.e("MyBinder","陪你洗桑拿");
}
public void PlayMajiang(){
Log.e("MyBinder","陪你打麻将");
}
@Override
public void Dosomething() {
PalyMp3();
}
}
}
这段是aidl下访问的Service代码:
package com.sxt.lp.phonelistener;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.os.IInterface;
import android.support.annotation.Nullable;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
/**
* Created by qw on 2016/11/9.
*/
public class PhoneListenerService extends Service {
public static String TAG = “PhoneListenerService”;
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "反回binder对象");
return new MyBinder();
}
private class MyBinder extends IAidlInterface.Stub {
public MyBinder() {
super();
}
public void Xisangna(){
Log.e("--------","陪官员洗桑拿");
}
public void PlayMajiang(){
Log.e("--------","陪官员打麻将");
}
@Override
public void Dosomething() {
}
}
public void PalyMp3() {
Log.e("PhoneListenerService", "我是服务的方法 为您播放一段音乐");
}
}
区别仅仅是Mybinder的实现变为继承aidl接口的实现类
当然这个时候远程调用服务者在ServiceConnection的自定义实现类中也不能简简单单的接受Binder对象了
这是caller的代码:
“`
package com.sxt.lp.callservice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
//aidl android interface defination lauague 安卓接口定义语言
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view){
Intent intent = new Intent();
intent.setAction("com.service.lp");
bindService(intent, new MyConnection(), Context.BIND_AUTO_CREATE);
}
public void callService(View view){
}
private class MyConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
com.sxt.lp.phonelistener.IAidlInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
}
“`除了这两个类之外你只需要在caller 和Service项目的相同的包名下建立相同的aidl文件而已,切记保证包名一致为Service的包名