这两个应用的实现很简单,就是实现在客户端点击“设置用户名”按钮往服务端输入用户名,然后又在客户端点击“获取用户名”按钮,获取服务端保存的用户名。
继承Service类的远程服务类代码如下:
package com.feixun.hu.ipc.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class IpcService extends Service { //用于保存客户端输入的用户名 private String userName; private ServiceBinder mServiceBinder; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); //创建ServiceBinder对象(Binder类型对象) mServiceBinder = new ServiceBinder(); } /*定义一个继承IMyService接口内部类Stub的实现与客户端通信的Binder类型的类, * IMyService.Stub是Binder类型 */ public class ServiceBinder extends IMyService.Stub { @Override public String getName() throws RemoteException { // TODO Auto-generated method stub return userName; } @Override public void setName(String name) throws RemoteException { // TODO Auto-generated method stub userName = name; } } @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub /*与客户端连接时,返回该Binder对象. * 1.如果连接的客户端和该服务端属于同一个进程,则此处直接返回mServiceBinder本身 * 2.如果连接的客户端和该服务不属于同一个进程,则返回的是mServiceBinder对象的代理 */ return mServiceBinder; } }AndroidManifest.xml文件代码如下: ( 注:文件中添加的action-->"com.feixun.hu.action.IPC_SERVICE"对应的是在客户端中绑定该服务设置添加的action)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.feixun.hu.ipc.service" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <service android:name=".IpcService"> <intent-filter > <action android:name="com.feixun.hu.action.IPC_SERVICE"/> </intent-filter> </service> </application> </manifest>
本文所谓的服务端,也就是创建一个应用程序工程,该应用程序包含一个Service。所以,该服务端应用程序运行时是不可见的。
客户端:一个继承Activity的类,和服务端一摸一样的IMyService.aidl文件(这个文件是实现两者之间进行通信必不可少的。可以直接把服务端自动生成的IMyService.java复制过去客服端)。
继承Activity的可视化类的代码如下:
package com.feixun.hu.ipc.client; import android.app.Activity; import android.app.Service; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class IpcClient extends Activity { private IMyService mIMyService; private Button setName, getName; private TextView show; private EditText input; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //获取各组件 setName = (Button)findViewById(R.id.set); getName = (Button)findViewById(R.id.get); show = (TextView)findViewById(R.id.show); input = (EditText)findViewById(R.id.input); //创建Intent,对应服务端注册的Intent Intent intent = new Intent(); intent.setAction("com.feixun.hu.action.IPC_SERVICE"); //绑定连接远程服务 bindService(intent, conn, Service.BIND_AUTO_CREATE); //为设置按钮绑定监听 setName.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(input.getText() != null) { try { //将输入的信息保存到远程服务端 mIMyService.setName(input.getText().toString()); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); //获取按钮绑定监听 getName.setOnClickListener(new OnClickListener() { //String name = mIMyService.getName(); @Override public void onClick(View v) { // TODO Auto-generated method stub try { if(mIMyService.getName() != null) { show.setText(mIMyService.getName().toString()); } } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } //实现客户端与服务端绑定的关键部分 private ServiceConnection conn = new ServiceConnection() { //解除连接服务端 @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mIMyService = null; } //连接服务端 @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub /*此处实现获取通过IpcService的onBind方法返回的mServiceBinder对象的代理。 * 参数service为绑定获得的远程服务IpcService的mServiceBinder对象, * 而调用IMyService.Stub的函数asInterface获取的是mServiceBinder对象的代理。 */ mIMyService = IMyService.Stub.asInterface(service); } }; @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); //解除绑定 unbindService(conn); } }main.xml文件的代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/set" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/setName"/> <EditText android:id="@+id/input" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/info"/> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/get" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/getName"/> <TextView android:id="@+id/show" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
本文所谓的客户端,也是创建一个应用程序工程,该工程包含一个Activity,用户通过操作该Activity所提供的可视化组件界面,向远处服务端(也就是在另一个应用程序进程中运行的Service服务)保存数据、获取数据。
以上两个简单的应用程序例子,可以实现两个应用程序之间的最基本的跨进程通信了。当然,有需要时,我们还可以创建传输和处理更复杂的数据远程服务,而不单单是本文所创建的例子那么简单。比如,以一个类的形式(类似JavaBean)为数据,而此时,这个数据类是要求要实现Parcelable接口的。(根据AIDL文件定义的接口限定的数据类型要求的)