Messenger的使用
2016-04-19 18:07
495 查看
在Android编程中,要想实现IPC,有如下几种方法:
1,使用AIDL,在需要实现多线程和并发处理时使用
2,继承Binder类来实现
3,使用Messenger
这一节我们研究Messenger的使用。以后有机会研究前两种。
首先,通过查看Messenger的源代码,我们可以看到它有两个构造函数:
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
和
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
前者用来给服务端调用创建Messenger,后者给客户端调用。
使用上述Handler创建一个
上述Messenger对象创建一个
服务端的onBind()返回该对象给客户端
客户端使用上述IBinder对象初始化Messenger对象(该对象引用服务端的Handler),然后服务端就可以使用它来发生
服务端在它的Handler对象中收到上述Message对象,使用
使用这种方式,不存在客户端调用服务端的“方法”,而是客户端发送“信息”(即Message对象),服务端在它的Handler中接收并处理。
如下是使用Messager的服务端的代码:
上述
客户端只需要使用服务端返回的IBinder创建Messenger对象,然后使用该对象的send()方法发生消息即可。代码如下(先绑定服务,然后发送
上述示例没有显示服务端如何响应客户端。如果需要服务端响应的话,需要将客户端创建的Messenger对象赋值给的Message的replyTo参数,如下:
服务端:public class MessengerService extends Service {
public static final int MSG_TAG_REMOTE = 0x110;
public static final int MSG_TAG_CLIENT = 0x111;
private int mCounter = 0;
class ServiceHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TAG_REMOTE:
Messenger client = msg.replyTo;
try {
client.send(Message.obtain(null, MSG_TAG_CLIENT, ++mCounter,0));
} catch (RemoteException e) {
e.printStackTrace();
}
}
super.handleMessage(msg);
}
}
final Messenger mMessenger = new Messenger(new ServiceHandler());
/* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
*/
@Override
public IBinder onBind(Intent intent) {
return (mMessenger == null) ? null : mMessenger.getBinder();
}
}
客户端:
public class MessengerServceActivity extends Activity {
private TextView mTextView;
private Messenger mServiceMessenger;
final Messenger mClientMessenger = new Messenger(new ClientHandler());
ServiceConnection mServiceConn = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mServiceMessenger = new Messenger(service);
Message msg = Message.obtain(null, MessengerService.MSG_TAG_REMOTE);
msg.replyTo = mClientMessenger;
try {
mServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceMessenger = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one_textview);
mTextView = (TextView) findViewById(R.id.content_show);
bindService(new Intent(this, MessengerService.class), mServiceConn, BIND_AUTO_CREATE);
}
class ClientHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MessengerService.MSG_TAG_CLIENT:
if (mTextView != null) {
mTextView.setText(msg.arg1+"");
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
1,使用AIDL,在需要实现多线程和并发处理时使用
2,继承Binder类来实现
3,使用Messenger
这一节我们研究Messenger的使用。以后有机会研究前两种。
首先,通过查看Messenger的源代码,我们可以看到它有两个构造函数:
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
和
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
前者用来给服务端调用创建Messenger,后者给客户端调用。
使用方法
首先,服务端实现一个Handler,用来接收客户端的信息
使用上述Handler创建一个
[code]Messenger[/code] 对象(它是Handler类中的一个引用,Handler类的成员变量mMessenger指向这个新创建的对象)。
上述Messenger对象创建一个
IBinder对象,
服务端的onBind()返回该对象给客户端
客户端使用上述IBinder对象初始化Messenger对象(该对象引用服务端的Handler),然后服务端就可以使用它来发生
Message对象给服务端。
服务端在它的Handler对象中收到上述Message对象,使用
handleMessage()方法来处理。
使用这种方式,不存在客户端调用服务端的“方法”,而是客户端发送“信息”(即Message对象),服务端在它的Handler中接收并处理。
如下是使用Messager的服务端的代码:
public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ final Messenger mMessenger = new Messenger(new IncomingHandler()); /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } }
上述
handleMessage()方法就是服务端接收消息并决定如何处理的地方。
客户端只需要使用服务端返回的IBinder创建Messenger对象,然后使用该对象的send()方法发生消息即可。代码如下(先绑定服务,然后发送
MSG_SAY_HELLO消息给服务端:
public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean mBound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mService = null; mBound = false; } }; public void sayHello(View v) { if (!mBound) return; // Create and send a message to the service, using a supported 'what' value Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } }
上述示例没有显示服务端如何响应客户端。如果需要服务端响应的话,需要将客户端创建的Messenger对象赋值给的Message的replyTo参数,如下:
服务端:public class MessengerService extends Service {
public static final int MSG_TAG_REMOTE = 0x110;
public static final int MSG_TAG_CLIENT = 0x111;
private int mCounter = 0;
class ServiceHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TAG_REMOTE:
Messenger client = msg.replyTo;
try {
client.send(Message.obtain(null, MSG_TAG_CLIENT, ++mCounter,0));
} catch (RemoteException e) {
e.printStackTrace();
}
}
super.handleMessage(msg);
}
}
final Messenger mMessenger = new Messenger(new ServiceHandler());
/* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
*/
@Override
public IBinder onBind(Intent intent) {
return (mMessenger == null) ? null : mMessenger.getBinder();
}
}
客户端:
public class MessengerServceActivity extends Activity {
private TextView mTextView;
private Messenger mServiceMessenger;
final Messenger mClientMessenger = new Messenger(new ClientHandler());
ServiceConnection mServiceConn = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mServiceMessenger = new Messenger(service);
Message msg = Message.obtain(null, MessengerService.MSG_TAG_REMOTE);
msg.replyTo = mClientMessenger;
try {
mServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceMessenger = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one_textview);
mTextView = (TextView) findViewById(R.id.content_show);
bindService(new Intent(this, MessengerService.class), mServiceConn, BIND_AUTO_CREATE);
}
class ClientHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MessengerService.MSG_TAG_CLIENT:
if (mTextView != null) {
mTextView.setText(msg.arg1+"");
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories