aidi跨进程通讯在android系统中使用广泛,包括client端和server端。今天写个简单例子记录下:
新建android工程:AIDL_Service(服务端)
选择Android为工程目录视图,在包名上右键新建aidl file,最后会在app/src/main目录下面
package reacheng.com.aidl_service; // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ int AIDL_ADD(in int a,in int b); }
新建好了之后编译工程
新建服务端的service
public class MyService extends Service { @Override public void onCreate() { super.onCreate(); android.util.Log.e("MyService","onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { android.util.Log.e("MyService","onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. android.util.Log.e("MyService","onBind"); return mBinder; } @Override public void onDestroy() { android.util.Log.e("MyService","onDestroy"); super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { android.util.Log.e("MyService","onUnbind"); return super.onUnbind(intent); } IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public int AIDL_ADD(int a, int b) throws RemoteException { return a+b; } };
清单文件配置,exported一定要设置成true,表示此服务可以被其他地方调用,process设置成远程服务
<service android:name=".MyService" android:process=":remote" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="reacheng.com.aidl_service.AIDL_Service"/> </intent-filter> </service>
至此服务端配置完成,运行...
新建android工程:AIDL_Client(客户端)
拷贝AIDL_Service端的aidl文件夹到客户端工程在app/src/main下面
界面放置三个按钮,分别是绑定,解绑,获取结果
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_centerInParent="true" android:id="@+id/bind_btn" android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="bind service" /> <Button android:layout_centerInParent="true" android:layout_below="@id/bind_btn" android:id="@+id/unbind_btn" android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="unbind sercice" /> <Button android:layout_centerInParent="true" android:layout_below="@id/unbind_btn" android:id="@+id/result_btn" android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="get result" /> </RelativeLayout>
client端主界面逻辑
public class MainActivity extends AppCompatActivity { private IMyAidlInterface iMyAidlInterface; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Toast.makeText(MainActivity.this,"service is disconnected",Toast.LENGTH_LONG).show(); } @Override public void onServiceConnected(ComponentName name, IBinder service) { iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); Toast.makeText(MainActivity.this,"service is connected",Toast.LENGTH_LONG).show(); } }; public void click(View view){ Intent intent = new Intent("reacheng.com.aidl_service.AIDL_Service"); //Android5.0后无法只通过隐式Intent绑定远程Service //需要通过setPackage()方法指定包名 intent.setPackage("reacheng.com.aidl_service"); switch (view.getId()){ case R.id.bind_btn: bindService(intent, connection, Context.BIND_AUTO_CREATE); break; case R.id.unbind_btn: unbindService(connection); break; case R.id.result_btn: try { //通过该对象调用在MyAIDLService.aidl文件中定义的接口方法,从而实现跨进程通信 final int result = iMyAidlInterface.AIDL_ADD(10,21); Toast.makeText(MainActivity.this,"result for service is : "+result,Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); } break; } } }
最后运行client 可以toast出结果...
至此,一个简单的aidl跨进程通讯完成,如果有错误,欢迎指正。