zoukankan      html  css  js  c++  java
  • android bind service 学习笔记

            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 (){
    
    	@Override
    	public void onServiceConnected(ComponentName name, IBinder service) {
    		// TODO Auto-generated method stub
    	}
    
    	@Override
    	public 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 block
    				e.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());
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		return 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 (){
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			// TODO Auto-generated method stub
    			mMessenger=new Messenger(service);//用service中返回的binder构建实例
    			send.setEnabled(true);
    		}
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			// TODO Auto-generated method stub
    			mMessenger=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() {
    		
    		@Override
    		public void showResult(){
    			// TODO Auto-generated method stub
    		//Toast.makeText(AidlService.this, "the toast show from AidlService", Toast.LENGTH_LONG).show();
    			Log.d("remoteservice","showResult");
    		}
    	};
    	@Override
    	public 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(){
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			// TODO Auto-generated method stub
    			mAidlService=IRemoteService.Stub.asInterface(service);
    			Log.d("ConMainActivity", "onServiceConnected");
    			try {
    				mAidlService.showResult();
    			} catch (RemoteException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			// TODO Auto-generated method stub
    			
    		}
    		
    	};


    源码下载地址:稍后奉上










  • 相关阅读:
    UWP Xaml设计器中输入特殊字符
    UWP DEP0700: 应用程序注册失败。[0x80073CF9] Install failed. Please contact your software vendor. (Exception from HRESULT: 0x80073CF9)
    UWP 使用Windows.Media.FaceAnalysis.FaceDetector检测人脸
    .Net Core和.Net Standard直观理解
    双屏互动h5
    前端发展趋势与开发技巧
    git学习总结
    前端路由
    【react开发】使用swiper插件,loop:true时产生的问题解决方案
    【纪念】我的大学同学名单
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3091451.html
Copyright © 2011-2022 走看看