android bind service 學習筆記

來源:互聯網
上載者:User

        bind service可以實現應用組件綁定本地的service,也可以綁定其他應用的service,在android中每個應用運行在

自己的虛擬機器中,每個虛擬機器對應linux核心中一個進程,所以綁定其他應用的service,可以實現處理序間通訊。

        binder是能進行遠程操作的對象的一個基類,一個輕量級的遠端程序呼叫機制,核心部分在IBinder類中定義。

這個類是一個IBinder類的實現,為建立一個本地實現對象提供了標準的支援,後面的綁定都是基於binder來實現。

        綁定本地的service並與之互動相對比較簡單,在service中建立一個binder執行個體,此執行個體中需要有一個public方法可供綁定者

調用,在此public 方法中返回service執行個體,這樣就可以調用service中的public方法了。binder執行個體通過onBind回調

方法返回給綁定者:

 

public class LocalService extends Service {    private final IBinder mBinder = new LocalBinder();    private final int mserviceparam=10; public class LocalBinder extends Binder {        LocalService getService() {            // Return this instance of LocalService so clients can call public methods            return LocalService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    /** method for clients */    public int getServiceParem(){      return mserviceparam;        }}

 綁定service通過以下方法實現:

 

 

bindService (Intent service, ServiceConnection conn, int flags)

ServiceConnection類中有兩個回調方法,當service綁定成功後和取消綁定會調用這兩個方法:

 

 

private ServiceConnection mConnection=new ServiceConnection (){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}};

        綁定不同應用的service並與之互動,需要藉助其他的類來實現,有兩種方式:messenger  、aidl

 

  1.messenger 中文翻譯“信使”,負責資訊的發送,可以跨進程,

   messenger有兩個建構函式:

     a .    public Messenger (Handler target) 

   handler是用來處理Messenger發送過來的message,

   即一個Messenger會有一個Handler與之相對應,

 通過Messenger.getBinder()獲得一個binder對象,在service的onBind()方法中返回給客服端      

 

public class MyService extends Service{ static final int MSG_SEND_FROM_REMOTE=1; static final int MSG_SEND_FROM_LOCAL=2; static final int MSG_RELY_FROM_SERVICE=3; class IncomingHandler extends Handler{  public void handleMessage(Message msg){ switch(msg.what){ case MSG_SEND_FROM_REMOTE: Toast.makeText(getApplicationContext(),"hello,i am from remote,send content is"+msg.getData().getString("sendContent"), Toast.LENGTH_LONG).show(); try {msg.replyTo.send(Message.obtain(null, MSG_RELY_FROM_SERVICE, null));} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();} break; case MSG_SEND_FROM_LOCAL: Log.d("remoteservice", "MSG_SEND_FROM_LOCAL"); Toast.makeText(getApplicationContext(),"hello,i am from local", Toast.LENGTH_LONG).show(); break;     default: super.handleMessage(msg); } }  } final Messenger mMessenger=new Messenger(new IncomingHandler());@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn mMessenger.getBinder();}}

 

 

      b.    public Messenger (IBinder target) 

       此建構函式一般用於綁定Service的組件中, 傳入的binder對象是從service返回的,這樣此Messenger就會與service中的

messenger相對應,用此Messenger發送訊息,在service中可以接受到,並做相應處理。

     到此我們只實現了從綁定組件發送訊息到service,service不能發送訊息給綁定組件,

 如要實現雙向通訊,則需要在綁定組件中再建立一個Messenger對象,用public Messenger (Handler target)構造方法,

把此Messenger賦值給msg.replyTo,一併發送到service中,service用此Messenger發送訊息給綁定組件

 

private ServiceConnection mConnection=new ServiceConnection (){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmMessenger=new Messenger(service);//用service中返回的binder構建執行個體send.setEnabled(true);}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubmMessenger=null;send.setEnabled(false);}};
class incomingHandler extends Handler{ //構建綁定組件的handler,service發送過來的message在此處理public void handleMessage(Message msg){switch(msg.what){case MSG_RELY_FROM_SERVICE:sendcontent.setText("service received");break;default:super.handleMessage(msg);}}}
private Messenger reMessenger=new Messenger(new incomingHandler());//構建綁定組件的Messenger

 

private void sendMessage() throws RemoteException{//發送訊息Message msg=Message.obtain(null, MSG_SEND_FROM_REMOTE, null);Bundle data=new Bundle();data.putString("sendContent",sendcontent.getText().toString());msg.setData(data);msg.replyTo=reMessenger;mMessenger.send(msg);Log.d("remoteservice", "sendMessage");}

2.AIDL android interface definition language 介面定義語言,

 

在src/ 目錄中建立一個以.aidl為尾碼名的介面定義檔案,android SDK工具會自動在 gen/ 目錄中建立名字一樣的java檔案,

java檔案是一個Ibinder介面檔案。

如定義的.aidl檔案為:

 

package txj.remoteservice;interface IRemoteService {      void showResult();}

會自動產生一個.java 檔案:

 

 

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: E:\\android\\newworkspase\\RemoteService\\src\\txj\\remoteservice\\IRemoteService.aidl */package txj.remoteservice;public interface IRemoteService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements txj.remoteservice.IRemoteService{private static final java.lang.String DESCRIPTOR = "txj.remoteservice.IRemoteService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an txj.remoteservice.IRemoteService interface, * generating a proxy if needed. */public static txj.remoteservice.IRemoteService asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof txj.remoteservice.IRemoteService))) {return ((txj.remoteservice.IRemoteService)iin);}return new txj.remoteservice.IRemoteService.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_showResult:{data.enforceInterface(DESCRIPTOR);this.showResult();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements txj.remoteservice.IRemoteService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public void showResult() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_showResult, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_showResult = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public void showResult() throws android.os.RemoteException;}

其中的stub抽象內部類繼承了binder和實現了自己定義的介面
 在service中需建立一個類extends Stub 並實現自己定義的介面方法,在onbind()方法中返回一個此類的對象。

 

 

public class AidlService extends Service {     private IRemoteService.Stub mbindder=new IRemoteService.Stub() {@Overridepublic void showResult(){// TODO Auto-generated method stub//Toast.makeText(AidlService.this, "the toast show from AidlService", Toast.LENGTH_LONG).show();Log.d("remoteservice","showResult");}};@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.return mbindder;} public void onDestroy(){ Log.d("remoteservice","onDestroy");  super.onDestroy(); }}    

把此.aidl檔案複製到需要綁定此服務的應用的src/ 檔案目錄中(包名也要一樣),也會在gen/中自動產生相對應的java檔案。

 

綁定組件在綁定成功後會得到service返回的binder,通過下面方法得到自己定義介面類型的對象,即可調用service中實現的方法:
mAidlService=IRemoteService.Stub.asInterface(service);

實現代碼:

 

private ServiceConnection mAidlConnection=new ServiceConnection(){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmAidlService=IRemoteService.Stub.asInterface(service);Log.d("ConMainActivity", "onServiceConnected");try {mAidlService.showResult();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}};

源碼:稍後奉上

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.