Android Service的Binder机制通信框架

原创
2014/12/04 22:26
阅读数 184

此外Service+Binder机制也可以实现很好的通信,但这种通信过于繁琐和过于侵入式,导致耦合问题非常严重。如下代码是使用Binder机制的中一种方式。

一、暴露接口方式

服务端

public class MyService extends Service {

	private final String tag = "MyService";
	
	@Override
	public IBinder onBind(Intent intent)
	{
		Log.d(tag, "onBind");
		return new MyBinder();
	}
	
	@Override
	public boolean onUnbind(Intent intent) {
		Log.d(tag, "onUnbind");
		return super.onUnbind(intent);
	}
	
	@Override
	public void onCreate() 
	{
		Log.d(tag, "onCreate");
		super.onCreate();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Log.d(tag, "onStart");
		super.onStart(intent, startId);
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) 
	{
		Log.d(tag, "onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		Log.d(tag, "onDestroy");
		super.onDestroy();
	}
	
	public class MyBinder extends Binder
	{  
	     MyService getService()  
	     {  
	        return MyService.this;  
	     }  
	}  
}

客户端

public  class MyServiceConnection implements  ServiceConnection
{
		private  Service mService = null;
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			mService = null;
			Log.d("ServiceClient", "绑定解除");
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mService = ((MyService.MyBinder) service).getService();
			Log.d("ServiceClient", "绑定成功");
			
		}
}

二、Binder 原生通信

服务端实现

/**
 * Created by Jay on 2015/8/18 0018.
 */
public class IPCService extends Service {

    private static final String DESCRIPTOR = "IPCService";
    private final String[] names = { "B神", "艹神", "基神", "J神", "翔神" };
    private MyBinder mBinder = new MyBinder();

    private class MyBinder 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;
    }
}

可以看到onTransact有四个参数 
code , data ,replay , flags

  • code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
  • data客户端传递过来的参数;
  • replay服务器返回回去的值;
  • flags标明是否有返回值,0为有(双向),1为没有(单向)。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText edit_num;
    private Button btn_query;
    private TextView txt_result;
    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("android.intent.action.IPCService");
        service.setPackage("com.jay.ipcserver");
        bindService(service, PersonConnection, BIND_AUTO_CREATE);
        btn_query.setOnClickListener(this);
    }

    private void bindViews() {
        edit_num = (EditText) findViewById(R.id.edit_num);
        btn_query = (Button) findViewById(R.id.btn_query);
        txt_result = (TextView) findViewById(R.id.txt_result);
    }

    @Override
    public void onClick(View v) {
        int num = Integer.parseInt(edit_num.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("IPCService");
                _data.writeInt(num);
                mIBinder.transact(0x001, _data, _reply, 0);
                _reply.readException();
                _result = _reply.readString();
                txt_result.setText(_result);
                edit_num.setText("");
            } catch (RemoteException e) {
                e.printStackTrace();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }
    }
}

 

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部