1. 定义一个AIDL接口
android工程目录下面创建一个.aidl扩展名的文件
// MyAIDLService.aidl package com.myservice; // Declare any non-default types here with import statements interface MyAIDLService { int plus(int a, int b); String toUpperCase(String str); }
2. 为远程服务(Service)实现对应Stub
package com.myservice;import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; /** * Created by 24720 on 2016/12/6. */ public class MyService extends Service{ public static final String TAG = "MyService"; @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate() executed\n"+android.os.Process.myPid()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return mbinder; } MyAIDLService.Stub mbinder=new MyAIDLService.Stub() { @Override public int plus(int a, int b) throws RemoteException { return a+b; } @Override public String toUpperCase(String str) throws RemoteException { if(str!=null){ return str.toUpperCase(); } return null; } }; @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy() executed"); } class MyBinder extends Binder { public void startDownload() { Log.d("TAG", "startDownload() executed"); // 执行具体的下载任务 } } }
在这里要注意Service是一个远程服务,在manifest的service里面加上 android:process=":remote" 就可以了,在MyService里面实现刚刚写的aidl接口,重写了plus和toUpperCase方法,这两个方法的作用分别是将一个字符串全部转换成大写格式,以及将两个传入的整数进行相加。然后在onBind()方法中将MyAIDLService.Stub的实现返回。这里为什么可以这样写呢?因为Stub其实就是Binder的子类,所以在onBind()方法中可以直接返回Stub的实现。
3. 将服务“暴露”给客户程序使用
package com.myservice;
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.util.Log; import android.view.View; import android.widget.Button; public class ServiceActivity extends Activity implements View.OnClickListener{ private Button bindService; private Button unbindService; private MyAIDLService myAIDLService; private String TAG="ServiceActivity"; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { myAIDLService=MyAIDLService.Stub.asInterface(iBinder); try { int result=myAIDLService.plus(3,6); String str=myAIDLService.toUpperCase("hello word"); Log.e(TAG,"result----"+result+";-------"+str); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName ) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service); Log.d("TAG", "process id is " + android.os.Process.myPid()); bindService = (Button) findViewById(R.id.bind_service); unbindService = (Button) findViewById(R.id.unbind_service); bindService.setOnClickListener(this); unbindService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bind_service: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent,connection,BIND_AUTO_CREATE); break; case R.id.unbind_service: Log.d("MyService", "click Unbind Service button"); unbindService(connection); break; default: break; } } }
在这个界面要注意一个方法ServiceConnection,这里首先使用了MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成了MyAIDLService对象,接下来就可以调用在MyAIDLService.aidl文件中定义的所有接口了。这里我们先是调用了plus()方法,并传入了3和6作为参数,然后又调用了toUpperCase()方法,并传入hello world字符串作为参数,最后将调用方法的返回结果打印出来。打印的结果com.myservice E/ServiceActivity: result----9;-------HELLO WORD,本文是看了郭林大神的贴子之后自己动手写的demo