Android组件通讯之可跨进程的远程Service调用
想要实现应用A调用应用B的Service,可以使用AIDL文件达到目的
首先创建一个RemoteService项目,在src文件夹下新建一个包com.moka.aidl,然后新建一个aidl文件如下:
1 package com.moka.aidl; 2 3 interface RemoteService { 4 String display(); 5 }
此“接口”内定义了要被远程调用的方法,保存完毕后,会自动在gen文件夹下生成对应的同名java接口如下图:
接下来编写我们自己的Service类:
1 public class MyService extends Service { 2 3 private MyBinder mybinder = new MyBinder(); 4 5 @Override 6 public IBinder onBind(Intent intent) { 7 return mybinder; 8 } 9 10 /* 11 * 系统自动生成的RemoteService.java接口类中有一个静态抽象内部类Stub 12 * 此类继承了Binder类,实现了生成的java接口类 13 * 使用他的方法一般是在Service中实现Stub的子类,在其中复写要被远程调用的方法 14 * 然后将其作为IBinder传回调用此Service的客户端 15 */ 16 class MyBinder extends RemoteService.Stub { 17 18 @Override 19 public String display() throws RemoteException { 20 return "成功远程调用了一个Service"; 21 } 22 23 } 24 }
别忘了注册Service,自定义一个Action方便其它应用远程调用:
1 <service android:name=".MyService" > 2 <intent-filter> 3 <action android:name="com.moka.action.REMOTE_SERVICE" /> 4 </intent-filter> 5 </service>
然后,新建第二个项目RemoteServiceTestProject,把刚刚项目中包含aidl文件的包复制到本项目的对应位置,gen内也会自动生成对应java接口
本项目Activity:
1 public class MainActivity extends Activity { 2 3 private Button testBtn = null; 4 private RemoteService rs = null; 5 6 private ServiceConnection conn = new ServiceConnection() { 7 8 @Override 9 public void onServiceDisconnected(ComponentName name) { 10 } 11 12 @Override
/* 因为有可能不止一个客户端调用,所以要保证线程安全 */ 13 synchronized public void onServiceConnected(ComponentName name, IBinder service) { 14 // asInterface()为自动生成的Java接口中的方法,将传入的IBinder转回我们定义的Interface 15 rs = RemoteService.Stub.asInterface(service); 16 try { 17 // 调用我们需要的方法 18 String str = rs.display(); 19 Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); 20 // 解绑Service 21 MainActivity.this.unbindService(conn); 22 } catch (RemoteException e) { 23 e.printStackTrace(); 24 } 25 } 26 }; 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.activity_main); 32 33 testBtn = (Button) findViewById(R.id.testBtn); 34 testBtn.setOnClickListener(new RemoteServiceListener()); 35 } 36 37 private class RemoteServiceListener implements OnClickListener { 38 39 @Override 40 public void onClick(View v) { 41 // 指定要启动的远程Service 42 Intent intent = new Intent("com.moka.aidl.RemoteService"); 43 // 指定Action 44 intent.setAction("com.moka.action.REMOTE_SERVICE"); 45 // 绑定远程Service 46 MainActivity.this.bindService(intent, conn, Context.BIND_AUTO_CREATE); 47 } 48 49 } 50 51 }
最后效果: