使用Messenger实现进程间通信(IPC)
来源:互联网 发布:满语翻译软件 编辑:程序博客网 时间:2024/05/16 09:35
我们在使用远程服务时,需要进行进程间通信,可以通过实现AIDL接口。编写aidl文件也比较麻烦,有么有什么比较简单的方法呢?Android系统中提供了Messenger类,可直接实现客户端和服务端的交互。
代码示例
server端:
public class MyService extends Service { Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Message reply = Message.obtain(msg); switch (msg.what) { case 100: reply.what = 100; try { Thread.sleep(2000); msg.replyTo.send(reply); } catch (InterruptedException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } break; } super.handleMessage(msg); } };private Messenger messenger = new Messenger(handler); @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); }}
定义了一个Messenger对象,用Handler进行实例化,在OnBind中返回IBinder对象。不要忘了AndroidManifest文件中注册,
<service android:name=".MyService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.windy.serverclient.MyService"></action> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></service>client端:
public class MainActivity extends AppCompatActivity {private Button btDownload;private TextView txtCon;private TextView download;private Messenger messenger;private boolean isConn;Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 100: download.setText("downloaded!"); break; } super.handleMessage(msg); }};private Messenger replyMessenger = new Messenger(handler);private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { messenger = new Messenger(service); isConn = true; txtCon.setText("server connected!"); } @Override public void onServiceDisconnected(ComponentName name) { messenger = null; isConn = false; txtCon.setText("server disconnected!"); }};@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService(); txtCon = (TextView) findViewById(R.id.txtCon); btDownload = (Button) findViewById(R.id.btDownload); download = (TextView) findViewById(R.id.download); btDownload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { download.setText("downloading..."); try { Message msgToServer = Message.obtain(null, 100); msgToServer.replyTo = replyMessenger; if (isConn) { messenger.send(msgToServer); } } catch (RemoteException e) { e.printStackTrace(); } } });}private void bindService() { Intent intent = new Intent(); intent.setAction("com.windy.serverclient.MyService"); bindService(intent, mConn, Context.BIND_AUTO_CREATE); }@Overrideprotected void onDestroy() { super.onDestroy(); unbindService(mConn); }}
先绑定服务bindService();
绑定成功后,根据返回的IBinder对象实例化Messenger;
通过Messenger的send方法将Message发送到服务端;
handler接收服务端返回的数据,更新。
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btDownload" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="download"/> <TextView android:id="@+id/txtCon" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/download" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
源码解析
Messenger的构造函数,
public Messenger(Handler target) { mTarget = target.getIMessenger();}public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target);}这两个构造函数在Demo中都有用到,目的都是为了实例化mTarget,
final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; }}private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.this.sendMessage(msg); }}
以Handler为参数的构造函数最终也是获得一个MessengerImpl对象,继承于IMessager.Stub,实现了send方法。
消息如何发送呢?
/** * Send a Message to this Messenger's Handler. * * @param message The Message to send. Usually retrieved through * {@link Message#obtain() Message.obtain()}. * * @throws RemoteException Throws DeadObjectException if the target * Handler no longer exists. */public void send(Message message) throws RemoteException { mTarget.send(message);}
从注释可以看出是将消息发送到实现该Messenger的Handler对象,最终执行handleMessage方法。并且建议我们使用obtain方法创建消息实例。
mTarget是IMessager实例,而IMessenger是一个aidl文件,就是一个远程通信接口,其中定义了send方法,
package android.os;import android.os.Message;/** @hide */oneway interface IMessenger { void send(in Message msg);}前面已看到MessengerImpl实现了send方法,其实最终就是通过Handler来发送消息。
0 0
- 使用Messenger实现进程间通信(IPC)
- 使用Messenger实现IPC通信
- 安卓IPC(进程间通信)之Messenger基本使用
- Android使用Messenger实现进程间通信
- 使用Messenger实现进程间通信
- Android进程间通信(IPC)之Messenger
- android-----IPC进程间通信之Messenger
- Android之进程间通信(IPC)-Messenger
- android进程间通信ipc Messenger (一)
- Messenger(信使)进程间通信使用
- Android进程间通信(三):使用Messenger实现进程间通信
- 进程间通信使用Messenger
- 使用Messenger实现IPC
- Android Messenger实现IPC通信
- Android IPC机制(一)开启多进程和用Messenger进程间通信
- 使用Messenger实现进程间的相互通信
- Android IPC 进程间通信机制之 Messenger
- Android IPC机制(二)用Messenger进行进程间通信
- 仓储模式
- Java中运用数组的四种排序方法
- Dagger2 使用继承方式,简化Component获取
- 欢快的使用Unity JSON吧
- 记录学习的点滴(Mybatis配置注册Mapper的方式)
- 使用Messenger实现进程间通信(IPC)
- [从头学绘画] 第38节 跆拳道二十四品势之9-忠武
- ThinkPHP 3.2 简单操作 Redis
- MP4 和 mp4v2lib的使用 和 分析器
- SQL 左外连接,右外连接,全连接,内连接
- swift中UIImagePickerController的使用(相册、图库)
- log4j日志详解
- Python爬虫“Hello World”级入门实例,使用正则表达式从中国天气网抓取数据
- 【USACO08JAN】洛谷1948 Telephone Lines