本技术博文计划分为三个系列:
一、AIDL的基础,http://blog.csdn.net/wangqiubo2010/article/details/78601666。
二、AIDL之Messenger.。
三、AIDL终极篇之AIDL架构设计,http://blog.csdn.net/wangqiubo2010/article/details/78625846。
本博文是AIDL系列的第二篇,Messenger。
Messenger的本质,只要记住以下三点即可。
1、Messenger内部已经封装好,同样采用的AIDL,只是Messenger中用一个先进先出的队列来对收到的信息进行管理,也就是通过一个队列让消息按顺序执行,因此是不支持多线程并发处理的。
2、Messenger因为内部原理是AIDL,因此本质还是IBinder。
3、Messenger核心是handler,客户端通过获取到服务端的handler(外壳是messenger)来给服务器发送信息,同样如果服务端要发送信息给客户端则客户端也必须把自己的handler(外壳是messenger)传给服务端。
明白以上三个核心,来看具体应用。
package com.example.myservice;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.Parcelable;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import com.example.wangqiubo.myaidl.Book;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wangqiubo on 2017/5/5.
*/
public class MessengerService extends Service {
private static ArrayList<Book> mBookList = new ArrayList<>();
@Override
public void onCreate() {
super.onCreate();
mBookList.add(new Book("乔布斯","1000","名人传"));
mBookList.add(new Book("雷军","1001","名人传"));
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
private static class MessengerHandler extends Handler{
public MessengerHandler() {
}
@Override
public void handleMessage(Message msg) {
// Debug.waitForDebugger();
if (0 == msg.what){
Log.d("messagerServer", "客户端发来了数据!");
Messenger clientMss = msg.replyTo;
Bundle bundle = new Bundle();
bundle.putString("testStr", "lllll");
bundle.putParcelable("serverBook",mBookList.get(0));
bundle.putParcelableArrayList("serverBooks", mBookList);
Message message = new Message();
message.what = 2;
Book book = bundle.getParcelable("serverBook");
List<Book> myBooks = bundle.getParcelableArrayList("serverBooks");
message.setData(bundle);
try {
clientMss.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}else {
super.handleMessage(msg);
}
}
}
private static Messenger messenger = new Messenger(new MessengerHandler());
}
以上为服务端的代码,重点如下。
1、定义一个Messenger 变量,Messenger 变量构造函数参数为一个Handler。
2、请看自定义的MessengerHandler ,和平时使用的handler没有本质区别,通过handleMessage来处理客户端发送过来的信息请求。
3、 Messenger clientMss = msg.replyTo; 这行中 msg.replyTo 即是客户端传过来的 Messenger(本质是handler) ,通过本对象则直接向客户端发送信息。
4、传给客户端的为 messenger.getBinder()。
再来看看客户端的代码:
package com.example.wangqiubo.myapplication;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Adapter;
import android.widget.ListView;
import com.example.wangqiubo.myaidl.Book;
import java.util.List;
public class Main2Activity extends AppCompatActivity {
private Messenger remoteMessenger = null;
private Messenger clientMessenger = null;
private ListView mListView = null;
private CustomBaseAdapter mAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new CustomBaseAdapter(this);
mListView = (ListView) this.findViewById(R.id.my_list_view);
mListView.setAdapter(mAdapter);
Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.example.myservice", "com.example.myservice.MessengerService");
intent.setComponent(componentName);
this.bindService(intent, mySer, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mySer = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//SDebug.waitForDebugger();
Log.d("messager", "连接服务!");
remoteMessenger = new Messenger(service);
Message message = Message.obtain(null,0);
Bundle mBundle = new Bundle();
mBundle.putString("aa","bb");
message.setData(mBundle);
ClientHanndler clientHanndler = new ClientHanndler();
Log.d("messagerLooper", clientHanndler.getLooper().toString());
clientMessenger = new Messenger(clientHanndler);
message.replyTo = clientMessenger;
try {
remoteMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private class ClientHanndler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 2:
//Debug.waitForDebugger();
Log.d("messager", "服务器进行了反馈!");
Bundle serverData = msg.getData();
if (null == serverData){
Log.d("messager", "serverData为空值");
return;
}
Book book = serverData.getParcelable("serverBook");
List<Book> books = serverData.getParcelableArrayList("serverBooks");
if (null != books && books.size() > 0)
Log.d("messager", "从服务器中已经获取到了数据");
else {
Log.d("messager", "从服务器中没有获取到了数据");
return;
}
mAdapter.setBookDatas(books);
mAdapter.notifyDataSetChanged();
break;
default:
break;
}
super.handleMessage(msg);
}
}
}
1、客户端的代码定义和服务端的定义基本一致,通过传过来的Binder转换成服务端的messenger,remoteMessenger = new Messenger(service)。
2、通过replayTo将客户端的messenger(本质处理信息的为handler)传递给服务器。