對於信使來說,我們不僅可以實現從客戶端向服務端傳遞數據,而且可以實現服務端和客戶端相互傳遞數據。
那麼我們是怎樣做到的呢?
在服務端:
①首先我們在服務端創建一個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是我們點擊按鈕發給服務端並在服務端處理輸出的,而界面中顯示的是服務端發給我們的信息,
如此就通過信使實現了服務端和客戶端的信息傳遞。