Android Service Binder 跨进程通信
可以使用 Android Binder
的 onTransact()
完成来完成跨进程通信
我们写一个 demo 来演示下如何使用
先来看看最后的效果图
-
创建一个 空的 Android 项目
cn.twle.android.IPCService
-
在
MainActivity.java
目录下新建服务端的 ServiceMsIPCService.java
package cn.twle.android.ipcservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; public class MsIPCService extends Service { private static final String DESCRIPTOR = "MsIPCService"; private final String[] names = {"Python","Perl","PHP","Java","Android"}; private MsBinder mBinder = new MsBinder(); private class MsBinder extends Binder { @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code){ case 0x001: { data.enforceInterface(DESCRIPTOR); int num = data.readInt(); reply.writeNoException(); reply.writeString(names[num]); return true; } } return super.onTransact(code, data, reply, flags); } } @Override public IBinder onBind(Intent intent) { return mBinder; } }
-
修改
AndroidManifest.xml
完成Service
注册,在</activity>
后添加<!-- 配置 Service 组件,同时配置一个 action --> <service android:name=".MsIPCService"> <intent-filter> <action android:name="cn.twle.android.ipcservice.MS_IPC_SERVICE"/> </intent-filter> </service>
-
修改
activity_main.xml
添加一个EditText
和Button
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请输入你要查询语言的序号" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number" android:id="@+id/lang_id" /> <Button android:text="查询" android:id="@+id/btn_search" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="match_parent" android:layout_marginLeft="16dp" android:layout_height="44dp" android:id="@+id/search_rs" android:text="" /> <TextView android:layout_marginTop="16dp" android:layout_marginLeft="16dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="0. Python\n1. Perl\n2. PHP\n3. Java\n4.Android" /> </LinearLayout>
-
修改
MainActivity.java
实现客户端package cn.twle.android.ipcservice; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private EditText lang_id; private Button btn_search; private TextView search_rs; private IBinder mIBinder; private ServiceConnection PersonConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mIBinder = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { mIBinder = service; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindViews(); //绑定远程Service Intent service = new Intent(this,MsIPCService.class); service.setPackage("cn.twle.android.ipcservice"); bindService(service, PersonConnection, BIND_AUTO_CREATE); btn_search.setOnClickListener(this); } private void bindViews() { lang_id = (EditText) findViewById(R.id.lang_id); btn_search = (Button) findViewById(R.id.btn_search); search_rs = (TextView) findViewById(R.id.search_rs); } @Override public void onClick(View v) { int num = Integer.parseInt(lang_id.getText().toString()); if (mIBinder == null) { Toast.makeText(this, "未连接服务端或服务端被异常杀死", Toast.LENGTH_SHORT).show(); } else { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); String _result = null; try{ _data.writeInterfaceToken("MsIPCService"); _data.writeInt(num); mIBinder.transact(0x001, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); search_rs.setText(_result); lang_id.setText(""); }catch (RemoteException e) { e.printStackTrace(); } finally { _reply.recycle(); _data.recycle(); } } } }