对于信使来说,我们不仅可以实现从客户端向服务端传递数据,而且可以实现服务端和客户端相互传递数据。
那么我们是怎样做到的呢?
在服务端:
①首先我们在服务端创建一个handler对象
②通过handler对象创建一个信使对象
③在onBind方法中通过信使对象的getBinder()方法返回一个IBinder对象
④在清单文件中配置服务的Action
在客户端:
①首先是通过Intent隐式绑定服务。
②实现ServiceConnection接口并重写其方法
③在其第一个方法中,通过其第二个参数service构建一个信使,该信使就是服务端传来的信使。
④通过发送消息的方式把要传递的数据封装到Bundle对象中,通过信使的sendMessage();方法传给服务端,同时,要声明一个handler对象,
然后构建客户端自己的信使对象,最后要通过Message对象的msg.replyTo方法把客户端的信使带给服务端。
⑤对于服务端,在handler对象的handleMessage方法中获取客户端传来的值和信使,然后通过该信使给客户端发送数据。
⑥在客户端的handler对象的handleMessage方法中通过msg.getData()得到服务端传来的Bundle对象并进而得到服务端传来的数据。
好了,描述了这么多,其实就几行代码就搞定了。
服务端:
package com.example.text07;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
//声明handler对象
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
//获取客户端传来的Bundle对象
Bundle bundle = msg.getData();
int count = bundle.getInt("count");
String info = bundle.getString("info");
Log.i("main", info + "--->" + count);
//获取客户端传来的信使
replyMessenger = msg.replyTo;
//服务端定义一个消息,再将消息给了replyMessenger
Message msg2 = Message.obtain();
Bundle bundle2 = new Bundle();
bundle2.putString("reply", "收到你的礼物了!");
msg2.setData(bundle2);
try {
//通过客户端传来的信使给客户端发送消息
replyMessenger.send(msg2);
} catch (RemoteException e) {
e.printStackTrace();
}
};
};
//创建信使对象
Messenger messenger = new Messenger(handler);
//声明一个信使对象用来接受客户端的信使对象
Messenger replyMessenger;
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
还有配置清单文件:
<service android:name="com.example.text07.MyService">
<intent-filter >
<action android:name="com.example.text07"/>
</intent-filter>
</service>
第二个Android项目中的客户端:
package com.example.text08;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et;
private TextView tv;
private MyServiceConn conn;
private Messenger serverMessenger;
private int count = 0;
// 创建一个handler对象用来获取服务端的消息
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
//获取服务端的消息
Bundle bundle = msg.getData();
String reply = bundle.getString("reply");
tv.setText("显示信息:" + reply);
};
};
// 声明客户端的信使
private Messenger replayMessenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.et);
tv = (TextView) findViewById(R.id.tv);
conn = new MyServiceConn();
//通过handler对象初始化客户端信使对象
replayMessenger = new Messenger(handler);
//通过在onCreate方法中使用隐式意图绑定服务
Intent intent = new Intent("com.example.text07");
boolean flag = bindService(intent, conn, BIND_AUTO_CREATE);
Log.i("main", "是否绑定成功?" + flag);
}
public void send(View view) {
//判断输入内容是否为空,使用的工具类
String info = et.getText().toString();
if (TextUtils.isEmpty(info)) {
Toast.makeText(this, "请输入内容", 0).show();
return;
} else {
//创建Message对象,对于字符串的传递要使用Bundle对象
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("info", info);
bundle.putInt("count", count++);
//把客户端自己的信使传过去
msg.replyTo = replayMessenger;
msg.setData(bundle);
try {
//让信使带走消息
serverMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
// 创建类
class MyServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serverMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
// Activity消失时解除绑定
@Override
protected void onStop() {
super.onStop();
if (conn != null) {
unbindService(conn);
}
}
}
好了,接下来我们看一下运行结果吧:下面的Log是我们点击按钮发给服务端并在服务端处理输出的,而界面中显示的是服务端发给我们的信息,
如此就通过信使实现了服务端和客户端的信息传递。