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相似。
书写步骤:
服务器端:
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文件进行操作的。
服务器端:
注册服务:
实现原理:
在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>