Android基本功:跨进程调用Services(AIDL Service)

一、AIDL Service简介  

Android系统中,各个应用都运行在自己的进程中,进程之间一般无法直接进行通信,为了实现进程通信(interprocess communication,简称IPC),Android提供了AIDL Service;  

  

二、与本地Service不同 

  • 本地Service:直接把IBinder对象本身传递给客户端的ServiceConnection的onServiceConnected方法的第二个参数; 

  • 远程Service:只将IBinder对象的代理传给客户端的ServiceConnection的onServiceConnected方法的第二个参数; 

 

三、AIDL文件  

Android需要AIDL(Android Interface Definition Language)来定义远程接口,这种接口定义语言并不是一种真正的变成语言,只是定义两个进程之间的通信接口 

 

与Java接口相似,但是存在如下几点差异  

  • AIDL定义接口的源代码必须以.aidl结尾  

  • AIDL用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其它类型全部都需要导包,即使它们在同一个包中也需要导包; 

 

四、使用AIDL的步骤(详细代码可见AIDLService和AIDLClient项目 

1.创建AIDL文件 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.aidlservice;   
  2.    
  3. interface ICat {   
  4.     String getColor();   
  5.     double getWeight();   
  6. }   
定义好AIDL文件后,ADT工具会自动在gen/com/example/aidlservice/目录下生成一个ICat.java接口,该类内部包含一个Stub内部类,实现了IBinder,ICat两个接口,这个Stub类会作为远程Service回调类;  

 

2.将接口暴露给客户端 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.aidlservice;   
  2. import java.util.Timer;   
  3. import java.util.TimerTask;   
  4. import com.example.aidlservice.ICat.Stub;   
  5. import android.app.Service;   
  6. import android.content.Intent;   
  7. import android.os.IBinder;   
  8. import android.os.RemoteException;   
  9.    
  10. public class AidlService extends Service {   
  11.     String[] colors = new String[] { "红色""黄色""黑色" };   
  12.     double[] weights = new double[] { 2.33.11.58 };   
  13.     private String color;   
  14.     private double weight;   
  15.     private CatBinder catBinder;   
  16.     Timer timer = new Timer();   
  17.    
  18.     @Override   
  19.     public void onCreate() {   
  20.         super.onCreate();   
  21.         catBinder = new CatBinder();   
  22.         timer.schedule(new TimerTask() {   
  23.    
  24.             @Override      
  25.             public void run() {   
  26.                 // 随机地改变service组件内的color,weight属性的值   
  27.                 int rand = (int) (Math.random() * 3);     
  28.                 color = colors[rand];   
  29.                 weight = weights[rand];   
  30.                 System.out.println("---------" + rand);   
  31.             }   
  32.         }, 0800)};   
  33.    
  34.     @Override   
  35.     public IBinder onBind(Intent arg0) {   
  36.         /**    
  37.         * 返回CatBinder对象,在绑定本地Service情况下,  
  38.         * 该catBinder会直接传给客户端的ServiceConnected对象的ServiceConnected  
  39.         * ()方法的第二个参数;在绑定远程Service的情况下   
  40.         * ,只将catBinder对象的代理传给客户端的ServiceConnected对象的ServiceConnected()方法的第二个参数  
  41.         */   
  42.         return catBinder;   
  43.     }   
  44.    
  45.     @Override   
  46.     public void onDestroy() {   
  47.         timer.cancel();   
  48.     }   
  49.    
  50.     /**     
  51.     * 继承Stub,也就是实现了ICat接口,并实现了IBinder接口  
  52.     *   
  53.     * @author pengcx  
  54.     *  
  55.     */   
  56.     public class CatBinder extends Stub {   
  57.         @Override   
  58.         public String getColor() throws RemoteException {   
  59.             return color;   
  60.         }   
  61.    
  62.     @Override   
  63.         public double getWeight() throws RemoteException {   
  64.             return weight;   
  65.         }   
  66.     }   
  67. }   

在AndroidManifext.xml文件中配置该Service;

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <service android:name="com.example.aidlservice.AidlService" >   
  2.     <intent-filter>   
  3.         <action android:name="org.crazyit.aidl.action.AIDL_SERVICE" />   
  4.     </intent-filter>   
  5.  </service>   
 

3.客户端访问AIDLService 

将Service端的AIDL文件复制到客户端中,注意要在相同的包名下 

 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.aidlclient;   
  2.    
  3. import com.example.aidlservice.ICat;   
  4. import android.os.Bundle;   
  5. import android.os.IBinder;   
  6. import android.os.RemoteException;   
  7. import android.view.View;   
  8. import android.view.View.OnClickListener;   
  9. import android.widget.Button;   
  10. import android.widget.EditText;   
  11. import android.app.Activity;   
  12. import android.app.Service;   
  13. import android.content.ComponentName;   
  14. import android.content.Intent;   
  15. import android.content.ServiceConnection;   
  16.    
  17. public class AidlClient extends Activity {   
  18.     private ICat catService;   
  19.     private Button getButton;   
  20.     private EditText colorEditText, weightEditText;   
  21.    
  22.     private ServiceConnection conn = new ServiceConnection() {   
  23.         @Override   
  24.         public void onServiceDisconnected(ComponentName name) {   
  25.             catService = null;   
  26.         }   
  27.    
  28.         @Override   
  29.         public void onServiceConnected(ComponentName name, IBinder service) {   
  30.             // 获取远程Service的onBinder方法返回的对象代理   
  31.             catService = ICat.Stub.asInterface(service);   
  32.         }   
  33.     };   
  34.    
  35.     @Override   
  36.     protected void onCreate(Bundle savedInstanceState) {   
  37.         super.onCreate(savedInstanceState);   
  38.         setContentView(R.layout.activity_aidl_client);   
  39.    
  40.         getButton = (Button) findViewById(R.id.getbutton);   
  41.         colorEditText = (EditText) findViewById(R.id.coloredittext);   
  42.         weightEditText = (EditText) findViewById(R.id.weightedittext);   
  43.    
  44.         // 创建所需要绑定的Service的Intent   
  45.         Intent intent = new Intent();   
  46.         intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE");   
  47.         // 绑定远程的服务   
  48.         bindService(intent, conn, Service.BIND_AUTO_CREATE);   
  49.                
  50.         getButton.setOnClickListener(new OnClickListener() {   
  51. @Override   
  52. public void onClick(View v) {   
  53.     // 获取并显示远程service的状态   
  54.     try {   
  55.         colorEditText.setText(catService.getColor());   
  56.         weightEditText.setText(catService.getWeight() + "");   
  57.     } catch (RemoteException e) {   
  58.         e.printStackTrace();   
  59.     }   
  60. }   
  61.        });   
  62.     }   
  63.    
  64.     @Override   
  65.     protected void onDestroy() {   
  66.         super.onDestroy();   
  67.         // 解除绑定   
  68.         this.unbindService(conn);   
  69.     }   
  70. }   
 

错误:java.lang.SecurityException: Binder invocation to an incorrect interface。在使用上请注意,服务端与客户端都要有相同的接口(使用到的),这里的“相同”是指完全相同,包括包名,也就是说要在不同工程下建立相同的包名 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值