Android服務之信使應用之二

對於信使來說,我們不僅可以實現從客戶端向服務端傳遞數據,而且可以實現服務端和客戶端相互傳遞數據。

那麼我們是怎樣做到的呢?

在服務端:

①首先我們在服務端創建一個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是我們點擊按鈕發給服務端並在服務端處理輸出的,而界面中顯示的是服務端發給我們的信息,

如此就通過信使實現了服務端和客戶端的信息傳遞。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章