环境
android studio 2.2
步骤:创建aidl文件,编写service,activity中绑定service
在项目上点击创建 aidl文件,会自动创建相关目录和文件 app/aidl/jlsky.myaidl/IMaidl.aidl。修改文件如下
package jlsky.myaidl;
interface IMaidl {
int sum(int num1,int num2);
}
ctrl+F9,或者点击那个锤子的图标,生成java代码。如果不是深入研究,生成的java文件就不用关心了。
创建service文件。
public class SumService extends Service {
private static final String TAG = "service";
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
private IMaidl.Stub iBinder = new IMaidl.Stub(){
@Override
public int sum(int num1,int num2) throws RemoteException{
return num1 + num2 ;
}
};
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, " onCreate");
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, " onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.i(TAG, " onDestroy");
super.onDestroy();
}
}
重点是private IMaidl.Stub iBinder = new IMaidl.Stub()中的<IMaidl>要与你的aidl的文件名一致。里面实现的方法就是在aidl中的声明一致。
然后这个<iBinder>在service被绑定时,通过onBind()返回给activity。
在activity中绑定service。
比如在activity的onCreate中绑定service
Intent intent = new Intent();
intent.setComponent(new ComponentName("jlsky.myaidl","jlsky.myaidl.SumService"));
//intent.setAction("jlsky.myaidl.SumService"); //如此写是错误的!
boolean b = bindService(intent,conn,BIND_AUTO_CREATE);
intent的参数是service的包名和service的全称。
b,不是必要的,但可以判断b的值来了解是否绑定成功。
事先声明一下
private IMaidl maidl; //与aidl文件名一致。
conn的来历如下,(直接放在activity中即可。)
private ServiceConnection conn = new ServiceConnection(){
// private class Conn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder){
maidl = IMaidl.Stub.asInterface(iBinder);
Log.d(TAG, "onServiceConnected: aidl");
}
@Override
public void onServiceDisconnected(ComponentName name){
maidl=null;
Log.d(TAG, "onServiceDisconnected: aidl");
}
};
activity的完整代码如下:
public class MainActivity extends Activity {
private EditText tv1,tv2;
private TextView tv3;
private Button btnSum;
private IMaidl maidl; //from ServiceConnection
private final static String TAG ="MainActivity";
// private ServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindaidl();
Log.d(TAG, "onCreate: bindaidl");
initview();
Log.d(TAG, "onCreate: initview");
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
Log.d(TAG, "onDestroy: unbindService");
}
private void initview() {
tv1=(EditText)findViewById(R.id.tv1);
tv2=(EditText)findViewById(R.id.tv2);
tv3=(TextView)findViewById(R.id.tv3);
btnSum=(Button)findViewById(R.id.btnSum);
btnSum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String str1,str2;
str1=tv1.getText().toString();
str2=tv2.getText().toString();
if(str1.length()>0 && str2.length()>0){
int data1,data2,result;
try{
result = maidl.sum(Integer.parseInt(str1),Integer.parseInt(str2));
Log.d(TAG, "onClick: result"+result);
// tv3.setText(""+result); //int to String
tv3.setText(String.valueOf(result));//int to String
} catch (RemoteException e) {
e.printStackTrace();
}
}else{
Toast.makeText(getApplicationContext(),"Pls input",Toast.LENGTH_SHORT).show();
}
}
});
}
private void bindaidl(){
Intent intent = new Intent();
intent.setComponent(new ComponentName("jlsky.myaidl","jlsky.myaidl.SumService"));
//intent.setAction("jlsky.myaidl.SumService"); //it is failed for here !
boolean b = bindService(intent,conn,BIND_AUTO_CREATE);
if(b){
Log.d(TAG, "bindaidl: ok");
}else{
Log.d(TAG, "bindaidl: fault");
}
}
private ServiceConnection conn = new ServiceConnection(){
// private class Conn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder){
maidl = IMaidl.Stub.asInterface(iBinder);
Log.d(TAG, "onServiceConnected: aidl");
}
@Override
public void onServiceDisconnected(ComponentName name){
maidl=null;
Log.d(TAG, "onServiceDisconnected: aidl");
}
};
}
manifest中的定义如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jlsky.myaidl">
<application ...>
<service
android:name=".SumService"
android:enabled="true"
android:exported="true"
android:process=":sum">
<intent-filter>
<action android:name="jlsky.myaidl"></action>//用来启动服务
</intent-filter>
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这个定义是让service单独作为一个进程(不是线程)。省略包名的默认写法。定义为私有线程,这与以点作为分割的公有线程不同。
android:process=":sum"
贴出来的代码都是反复实验的结果。有些测试由于记不住了是怎么回事,以免误导,就不写说明了。