以前学习的时候在eclipse上使用过AIDL,最近想学习下PackageManager,就先对AIDL复习下。网上很多都是在同一个进程中的例子,这次是在Android Studio上进行开发的,而且久了忘了比较多,觉得还是自己整理一份出来,下次再用的时候不用太折腾。
一、创建服务端
服务端目录结构:
1. 创建main/aidl/com.scott.IPerson.aidl文件。创建之后clean Project就可以在下图目录中看到系统自动生成的IPerson接口文件。若未生成,可以检查Iperson.aidl文件的包名是否和目录结构的一致。
2. 创建main/java/com.scott.server.AIDLService文件。
public classAIDLService extendsService {
private static final StringTAG ="AIDLService";
IPerson.Stub stub= new IPerson.Stub() {
@Override
public Stringgreet(Stringsomeone)throws RemoteException {
Log.i(TAG,"greet()called");
return "hello, " + someone;
}
};
@Override
public IBinderonBind(Intent intent) {
Log.i(TAG,"onBind()called");
return stub;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"onUnbind()called");
return true;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy() called");
}
}
3.在AndroidManifest.xml中配置AIDLService。
<service android:name=".AIDLService"> <intent-filter> <action android:name="android.intent.action.AIDLService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
二、创建客户端。
客户端目录结构:
1. 将/aidl/com.scott.IPerson.aidl整个目录结构复制到客户端的src/main/文件夹下,之后clean Project。你也可以自己手动创建/aidl/com.scott/目录结构,但必须注意该目录结构必须与服务端的目录结构相同,否则是连接不上的。这样就保证了服务端和客户端具有一致的协议了。
2. 在Activity中绑定&解绑服务AIDLServer。
public class ClientMainActivity extends AppCompatActivity { private Button bindBtn; private Button greetBtn; private Button unbindBtn; private IPerson person; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("ServiceConnection", "onServiceConnected() called"); person = IPerson.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { //This is called when the connection with the service has been unexpectedly disconnected, //that is, its process crashed. Because it is running in our same process, we should never see this happen. Log.i("ServiceConnection", "onServiceDisconnected() called"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_client_main); bindBtn = (Button) findViewById(R.id.bindBtn); bindBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("android.intent.action.AIDLService"); intent.setPackage("com.scott.server");//Android5.0+要求隐式启动Service必须设置Package bindService(intent, conn, Context.BIND_AUTO_CREATE); bindBtn.setEnabled(false); greetBtn.setEnabled(true); unbindBtn.setEnabled(true); } }); greetBtn = (Button) findViewById(R.id.greetBtn); greetBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String retVal = person.greet("scott"); Toast.makeText(ClientMainActivity.this, retVal, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { Toast.makeText(ClientMainActivity.this, "error", Toast.LENGTH_SHORT).show(); } } }); unbindBtn = (Button) findViewById(R.id.unbindBtn); unbindBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { unbindService(conn); bindBtn.setEnabled(true); greetBtn.setEnabled(false); unbindBtn.setEnabled(false); } }); } }
layout文件比较简单,就不上代码了。
Android手机是不允许Android两个包名一样的App的,所以本例中中Server的packageName为com.scott.server,Client的packageName为com.scott.client。但服务端和客户端aidl文件的文件路径必须一致。
本文主要代码还是参考http://blog.csdn.net/liuhe688/article/details/6400385,只是根据自己的理解方式进行一定整理。