service bound(二)
service 绑定有三种实现方式:
1. 直接继承Binder类实现。
条件: 同一应用,同一进程
2. 使用Messenger实现。
条件:要在不同的进程间通信,这种方式不用考虑线程安全性。(单线程操作时使用)
3. 使用AIDL实现。
条件:要在不同的进程间通信,并且需要多线程处理。要考虑线程之间的安全性。
通过Messenger实现bound service。
实现步骤:
handleMessage()
方法明确的处理.---service 要实现Handler,service通过Handler可以得到客户端的调用请求。
class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what) { case REGISTER: if(msg.replyTo != null && !messengerList.contains(msg.replyTo)){ messengerList.add(msg.replyTo) ; } Toast.makeText(getApplicationContext(), "bound", Toast.LENGTH_SHORT).show(); break; case UNREGISTER: if(msg.replyTo != null && messengerList.contains(msg.replyTo)){ messengerList.remove(msg.replyTo) ; } Toast.makeText(getApplicationContext(), "unbound", Toast.LENGTH_SHORT).show(); break; case REPLYTO: Message message = Message.obtain(null, 1, 0, 0); Bundle data = new Bundle() ; data.putString("REPLYTO", "reply from service") ; message.setData(data) ; try { msg.replyTo.send(message) ; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } default: super.handleMessage(msg); break; } } }
private Messenger messenger = new Messenger(new MessengerHandler()) ;
---Messenger创建一个IBinder,client调用onBind()时,IBinder返回给client的
@Override public IBinder onBind(Intent intent) { return messenger.getBinder(); }
---Clients 通过IBinder实例化Messenger
@Override public void onServiceConnected(ComponentName name, IBinder service) { mService = new Messenger(service); //通过IBinder 实例化Messenger mBound = true ; registerService(); }
handleMessage()
方法明确的处理.
try { Message msg = Message.obtain(null , MessengerService.REGISTER,0,0) ; msg.replyTo = mMessenger ; mService.send(msg) ; } catch (RemoteException e) { e.printStackTrace(); }
package com.hualu.serviceexample.messenger; import java.util.ArrayList; import java.util.List; 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.widget.Toast; /** * 测试不在同一个进程中, 不需要考虑线程安全性 * @author Administrator * */ public class MessengerService extends Service { final static int REGISTER = 1; final static int UNREGISTER = 2; final static int REPLYTO = 3; private Messenger messenger = new Messenger(new MessengerHandler()) ; private List<Messenger> messengerList = new ArrayList<Messenger>() ; @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); } class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what) { case REGISTER: if(msg.replyTo != null && !messengerList.contains(msg.replyTo)){ messengerList.add(msg.replyTo) ; } Toast.makeText(getApplicationContext(), "bound", Toast.LENGTH_SHORT).show(); break; case UNREGISTER: if(msg.replyTo != null && messengerList.contains(msg.replyTo)){ messengerList.remove(msg.replyTo) ; } Toast.makeText(getApplicationContext(), "unbound", Toast.LENGTH_SHORT).show(); break; case REPLYTO: Message message = Message.obtain(null, 1, 0, 0); Bundle data = new Bundle() ; data.putString("REPLYTO", "reply from service") ; message.setData(data) ; try { msg.replyTo.send(message) ; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } default: super.handleMessage(msg); break; } } } }
package com.hualu.serviceexample.messenger; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.hualu.serviceexample.R; public class MessengerActivity extends Activity implements OnClickListener{ private Messenger mService ; private boolean mBound ; private Button messenger, unBound, replyFromService ; private TextView text ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_binder_messenger) ; text = (TextView)this.findViewById(R.id.textView1) ; messenger = (Button)this.findViewById(R.id.messenger) ; unBound = (Button)this.findViewById(R.id.unbound) ; replyFromService = (Button)this.findViewById(R.id.reply_from_service) ; messenger.setOnClickListener(this) ; unBound.setOnClickListener(this) ; replyFromService.setOnClickListener(this) ; } private ServiceConnection conn = new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = new Messenger(service); ; mBound = true ; registerService(); } @Override public void onServiceDisconnected(ComponentName name) { mService = null; mBound = false ; } } ; @Override protected void onStart() { super.onStart() ; boundService() ; }; @Override protected void onStop() { super.onStop() ; if(mBound){ unbindService(conn); mMessenger = null; mBound = false; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.messenger: boundService(); break; case R.id.unbound: unBoundService() ; break ; case R.id.reply_from_service: replyFromService() ; break; } } private void boundService() { bindService(new Intent("com.hualu.serviceexample.BIND_MESSENGER_SERVICE"), conn, Context.BIND_AUTO_CREATE) ; text.setText("bound") ; } private void registerService(){ try { Message msg = Message.obtain(null , MessengerService.REGISTER,0,0) ; msg.replyTo = mMessenger ; mService.send(msg) ; } catch (RemoteException e) { e.printStackTrace(); } } private void replyFromService() { if(mService != null){ try { Message msg = Message.obtain(null , MessengerService.REPLYTO,0,0) ; msg.replyTo = mMessenger ; mService.send(msg) ; } catch (RemoteException e) { e.printStackTrace(); } } } private void unBoundService() { if (mBound) { if(mService != null){ Message msg = Message.obtain(null , MessengerService.UNREGISTER,0,0) ; msg.replyTo = mMessenger ; try { mService.send(msg) ; } catch (RemoteException e) { e.printStackTrace(); } } unbindService(conn) ; mBound =false; mService = null; text.setText("unbound") ; } }; private Messenger mMessenger = new Messenger(new MessengerActivityHandler()) ; class MessengerActivityHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Bundle data = msg.getData() ; String str = data.getString("REPLYTO"); text.setText(str) ; break; default: super.handleMessage(msg); break; } } } }
activity中的registerService()和unBoundService()方法,发送消息到service中;
replyFromService()是既发送消息到service中,又收到service返回的消息。
与上面说的对应的是在service里面的Handler的handleMessage()里面
Layout文件的代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:orientation="vertical" > <Button android:id="@+id/messenger" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/messenger" /> <Button android:id="@+id/unbound" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/unbound_messenger" /> <Button android:id="@+id/reply_from_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/reply_from_service" /> <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="TextView" /> </LinearLayout>
Manifest中相关的code:
<activity android:name=".messenger.MessengerActivity"> <intent-filter> <action android:name="com.hualu.serviceexample.BIND_MESSENGER_ACTIVITY"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter> </activity> <service android:name=".messenger.MessengerService"> <intent-filter> <action android:name="com.hualu.serviceexample.BIND_MESSENGER_SERVICE"></action> </intent-filter> </service>