跨进程的通信 [IPC]

Messenger 信使
  实现原理:
  在server和client端通过Messenger信使传递信息,该对象就相当于一个信息的中转站,所有的信息都要通过这个对象
 来携带,客户端向服务器端发送信息就需要服务器的信使对象,然后他想要接收到消息,就需要创建自己的信使对象,
 然后把自己的Messenger对象作为消息中的一部分,传递给服务器端,然后服务器端就能够拿着客户端的信使给客户端
 发消息。
 Messenger的实现流程:
  1.在server端创建一个信使对象:Messenger serverMessenger = new Messenger(handler);
  2.client端要通过bindService的方法绑定服务器端。
  3.在server端的onBind方法中返回一个binder对象,通过服务器端的信使获得的。serverMessenger.getBinder()
  4.在客户端通过重写onServiceConnected的方法可以获得服务器端的信使。就可以向服务器端发送消息。
  5.发送消息时,可以放入客户端的信使。
 小结:
  通过信使能够跨进程实现通信,底层是AIDL原理,和handler,thread相似。

实例:
客户端:

public class MainActivity extends Activity {
	private Messenger serverMessenger;

	private Messenger clientMessenger;
	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			Log.i("tag", "-----服务器传来的消息------");
			Log.i("tag", "arg1==" + msg.arg1 + ",arg2==" + msg.arg2);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		clientMessenger = new Messenger(handler);

	}

	ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 得到服务器端的信使
			serverMessenger = new Messenger(service);
		}
	};

	@Override
	protected void onStart() {
		super.onStart();
		Intent intent = new Intent();
		intent.setAction("com.sdut.service");
		boolean b = bindService(intent, conn, BIND_AUTO_CREATE);
		if(b){
			Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
		}
	}

	public void click(View view) {

		Message message = Message.obtain();
		message.what = 1;
		message.arg1 = 68;
		message.replyTo = clientMessenger;
		try {
			serverMessenger.send(message);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
}
服务器端:

public class MyService extends Service {
	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) {
				Log.i("tag", "客户端传来的消息");
				Log.i("tag", "传来的消息:" + msg.arg1+" "+msg.arg2);
				Messenger clientMessage = msg.replyTo;
				Message message = Message.obtain();
				message.arg1 = 90;
				message.arg2 = 180;

				try {
					clientMessage.send(message);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		};
	};
	// 服务器端信使
	Messenger serviceMessage = new Messenger(handler);

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return serviceMessage.getBinder();
	}

}
注册服务:

 <service android:name="com.example.service.MyService">
            <intent-filter >
                <action android:name="com.sdut.service"/>
            </intent-filter>
        </service>
AIDL方式   Android  Interface  Definition  Language   适用于不同应用程序之间的远程服务

书写步骤:
服务器端:
1.在服务器端,在src的文件夹中创建一个.aidl文件,在这个文件中定义客户端需要远程访问服务器端的方法。
2.在.aidl文件当中定义的方法和普通方法是一致的都有返回值和参数。
3.在服务器端暴漏.aidl这个类,并且在服务端获取其内部类Stub的对象。
4.实现aidl当中的方法,并且把Stub的对象添加为onBind的返回值。
客户端:
1.复制服务器端的.aidl文件到客户端,注意相同包名,相同类名。
2.重写onServiceConnected方法时获取aidl文件的对象。
3.绑定服务
4.通过获取到的对象,调用方法,得到返回值。
实现原理:
Android内存当中会自带一块存放aidl的公共区域,服务端会通过aidl文件,把要传入客户端的内容写入进去。
然后在通过onBind方法返回binder对象(继承于Binder类实现了aidl接口的Stub对象)。然后把生成的binder
对象通过序列化的方式写入到共享区域当中。
客户端也需要一个aidl的文件,这样才能够获得服务器端在共享区域里存放的文件的内容,然后客户端通过绑定服务
得到Binder对象,这个binder对象其实就是共享区域中服务器端生成的binder的对象经过反序列化的方式生成的对象。
通过binder对象就能够获得到服务器传来的信息了。
注意:
1.服务器端和客户端其实是对同一个aidl文件进行操作的。

2.服务器端生成的binder对象和客户端得到的binder对象不是同一个对象,是有相同内容的两个对象。


实例:

客户端:

public class MainActivity extends Activity {

	private DataService dataService;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			
		}
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			dataService = DataService.Stub.asInterface(service);
		}
	};
	public void bind(View v){
		Intent intent = new Intent();
		intent.setAction("com.sdut.aidlserver");
		bindService(intent, conn, BIND_AUTO_CREATE);
		
	}
	public void getInfo(View view){
		try {
			String str = dataService.getInfo();
			int i = dataService.getValue("哈哈");
			
			Log.i("tag", "从服务器传回的数据:"+i+","+str);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		
	}

}

服务器端:

public class MyService extends Service{

	@Override
	public IBinder onBind(Intent intent) {
		Log.i("tag", "绑定服务成功");
		return mBinder;
	}
	
	DataService.Stub mBinder = new DataService.Stub() {
		
		@Override
		public int getValue(String info) throws RemoteException {
			return 189;
		}
		
		@Override
		public String getInfo() throws RemoteException {
			return "编程难,难于上青天!!!";
		}
	};
}

注册服务:

 <service android:name="com.example.service.MyService">
            <intent-filter >
                <action android:name="com.example.aidlserver"/>
            </intent-filter>
        </service>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值