Server端实现
1. 新建Server空项目,然后按如下方式新建IPerson.aidl文件:
2. 修改IPerson.aidl为:
package com.example.chemins.testlina;
interface IPerson {
String queryPerson(int num);
}
3. 接着按ctrl + f9重新编译,完成后,就会发现在Build目录下生成了IPerson.java文件:
打开这个java文件:
- 注意Stub这个内部类继承了Binder实现了IPerson接口,用来通信的。
- asInterface():将绑定成功的IBinder对象转化为IPerson对象。
- queryPerson():IPerson中的接口。
其他的我们可以不看,直接跳过,进行下一步。
4. 自定义AIDLService类。
- 继承Service类,同时也自定义了一个PersonQueryBinder类用来继承IPerson.Stub类。就是实现了IPerson接口和IBinder接口
- 实例化自定义的Stub类,并重写Service的onBind方法,返回一个binder对象!
package com.example.chemins.testlina;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class AIDLService extends Service{
private IBinder binder = new PersonQueryBinder();
private String[] names = {"B神","艹神","基神","J神","翔神"};
@Override
public IBinder onBind(Intent intent) {
return binder;
}
private final class PersonQueryBinder extends IPerson.Stub{
@Override
public String queryPerson(int num) throws RemoteException {
return query(num);
}
}
private String query(int num)
{
if(num > 0 && num < 5){
return names[num - 1];
}
return null;
}
}
5. 在AndroidManifest.xml文件中注册Service
<service android:name=".AIDLService">
<intent-filter>
<action android:name="android.intent.action.AIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
这里我们并没有提供Activity界面,但是改应用提供的Service可以供其他app来调用!
2.客户端
1.直接把服务端的那个aidl文件复制过来,然后在MainActivity中绑定本地Service的操作。
MainActivity代码如下:
- 自定义PersonConnection类实现ServiceConnection接口
- 以PersonConnection对象作为参数,调用bindService绑定远程Service
bindService(service,conn,BIND_AUTO_CREATE);
ps:第三个参数是设置如果服务没有启动的话,自动创建 - 和本地Service不同,绑定远程Service的ServiceConnection并不能直接获取Service的onBind( )方法
返回的IBinder对象,只能返回onBind( )方法所返回的代理对象,需要做如下处理:
iPerson = IPerson.Stub.asInterface(service);
再接着完成初始化,以及按钮事件等就可以了
package com.example.chemins.suilest;
import android.app.Activity;
import android.content.ComponentName;
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 android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.chemins.testlina.IPerson;
public class MainActivity extends Activity {
private EditText editnum;
private Button btnquery;
private TextView txtshow;
private IPerson iPerson;
private PersonConnection conn = new PersonConnection();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editnum = (EditText) findViewById(R.id.editnum);
btnquery = (Button) findViewById(R.id.btnquery);
txtshow = (TextView) findViewById(R.id.txtshow);
//绑定服务
Intent service = new Intent("android.intent.action.AIDLService");
bindService(service, conn, BIND_AUTO_CREATE);
btnquery.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String number = editnum.getText().toString();
int num = Integer.valueOf(number);
try {
//调用服务中IPerson接口实现的方法
txtshow.setText(iPerson.queryPerson(num));
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
//绑定连接情况的回掉
private final class PersonConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
//连接成功
//将Binder对象,转化为IPerson对象
iPerson = IPerson.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName name) {
iPerson = null;
}
}
@Override
protected void onDestroy() {
unbindService(conn);//解除绑定
super.onDestroy();
}
}
运行:
- 先启动AIDLServivce
- 再启动AIDLClient
- 输入查询序号,即可获得对应姓名! 当然也可以直接启动AIDLClient,也会获得同样效果
. 注意:
sdk的版本,高版本不能用。
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
参考:https://www.runoob.com/w3cnote/android-tutorial-service-3.html
源码下载:
1)使用AIDL完成进程间的简单通信
2)传递复杂数据的AIDL Service的实现