Service之跨进程调用服务ADIL详解(二)

AIDL 服务只支持有限的数据类型,如果用AIDL服务传递一些复杂的数据就需要做更一步处理,  AIDL 服务支持的数据类型如下:
1. Java 的基本数据类型(不需要import)
2. String 和CharSequence(不需要import)
3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型; (以上三种类型都不需要import)
4. AIDL 自动生成的接口  (需要import)
5. 实现Android.os.Parcelable 接口的类.  (需要import) 

要传递一个需要import 的数据类型的值(如: 实现Parcelable接口的类),除了要建立一个实现Parcelable 接口的类外, 还需要为这个类单独建立一个aidl 文件, 并使用parcelable 关键字进行定义。

########################################

下面编写一个可以传递Product对象的AIDL服务。

步骤1,新建类Product.java,实现Parcelable接口。代码如下:

Java代码   收藏代码
  1. package com.example.service07_aidlservice;  
  2.   
  3. import android.os.Parcel;  
  4. import android.os.Parcelable;  
  5.   
  6. public class Product implements Parcelable {  
  7.     private int id;  
  8.     private String name;  
  9.     private float price;  
  10.   
  11.     public Product() {  
  12.     }  
  13.   
  14.     public Product(Parcel in) {  
  15.         id = in.readInt();  
  16.         name = in.readString();  
  17.         price = in.readFloat();  
  18.     }  
  19.   
  20.     /* 
  21.      *  在Product 类中必须有一个静态常量,<strong>常量名必须为CREATOR</strong>,而且CREATOR 常量的数据类型必须是<strong>Parcelable.Creator</strong> 
  22.      */  
  23.     public static final Parcelable.Creator<Product> CREATOR = new Parcelable.Creator<Product>() {  
  24.         @Override  
  25.         public Product createFromParcel(Parcel in) {  
  26.             return new Product(in);  
  27.         }  
  28.   
  29.         @Override  
  30.         public Product[] newArray(int size) {  
  31.             return new Product[size];  
  32.         }  
  33.     };  
  34.   
  35.     @Override  
  36.     public int describeContents() {  
  37.         return 0;  
  38.     }  
  39.   
  40.     @Override  
  41.     public void writeToParcel(Parcel dest, int flags) {  
  42.         dest.writeInt(id);  
  43.         dest.writeString(name);  
  44.         dest.writeFloat(price);  
  45.     }  
  46.   
  47.    //getter 和 setter 省略  
  48. }  

 

步骤2 ,为这个类单独建立一个aidl 文件, 并使用parcelable 关键字进行定义,Product.aidl代码如下

Java代码   收藏代码
  1. parcelable Product;  // parcelable 首字母是小写  

 

 步骤3,新建IMyService.aidl文件,代码如下:

Java代码   收藏代码
  1. package com.example.service07_aidlservice;  
  2. import com.example.service07_aidlservice.Product;//必须导包  
  3. import java.util.Map;//可以不导包  
  4. interface IMyService {  
  5.     //由于product只用于输入,因此需要加in 修饰符  
  6.     Map getMap(in String country,in Product product);  
  7.     Product getProduct();  
  8. }  

 

步骤4,编写一个Seravice类,MyService.java代码如下:

 

Java代码   收藏代码
  1. package com.example.service07_service;  
  2. import java.util.HashMap;  
  3. import java.util.Map;  
  4. import android.app.Service;  
  5. import android.content.Intent;  
  6. import android.os.IBinder;  
  7. import android.os.RemoteException;  
  8. import com.example.service07_aidlservice.IMyService.Stub;  
  9. import com.example.service07_aidlservice.Product;  
  10.   
  11. public class MyService extends Service {  
  12.     private MyBinder myBinder;   
  13.     @Override  
  14.     public IBinder onBind(Intent intent) {  
  15.         return new MyBinder();  
  16.     }  
  17.   
  18.       /*  
  19.          * 该类继承了IMyService.Stub类而不是extends Binder类。 
  20.          * IMyService.Stub是Binder的子类。 
  21.          * 进程内的Service定义MyBinder内部类是继承Binder类。 
  22.          */  
  23.     private class MyBinder extends IMyService.Stub {  
  24.         @Override  
  25.         public Map getMap(String country, Product product)  
  26.                 throws RemoteException {  
  27.             Map map = new HashMap<String, String>();  
  28.             map.put("country", country);  
  29.             map.put("id", product.getId());  
  30.             map.put("name", product.getName());  
  31.             map.put("price", product.getPrice());  
  32.             map.put("product", product);  
  33.             return map;  
  34.         }  
  35.   
  36.         @Override  
  37.         public Product getProduct() throws RemoteException {  
  38.             Product product = new Product();  
  39.             product.setId(1234);  
  40.             product.setName("奔驰");  
  41.             product.setPrice(300000);  
  42.             return product;  
  43.         }  
  44.     }  
  45. }  

 

步骤5,在AndroidManifest.xml中注册Service,并去掉MianActivity的配置。

Java代码   收藏代码
  1. <service android:name="com.example.service07_service.MyService" >  
  2.           <intent-filter>  
  3.               <!-- 指定客户端调用AIDL服务所需要的Action -->  
  4.               <action android:name="com.example.service07.aidl" />  
  5.           </intent-filter>  
  6.  </service>  

  

   服务端的代码结构如下: 

 

 

步骤6,客户端的编写:新建客户端项目,把IMyService.aidl,Product.aidl,Product.java 连同包一起拷贝到Client的src目录。注意,实体类也要拷贝过去。这几个类最好放在一个包下,因为我放在不同的包下一直报错找不到类,即使我正确的导包了还是报错。

 

步骤7,编写MainActivity.java 和 xml布局文件;界面提供了2个按钮。BIND 按钮 和 INVOKE 按钮.

    

Java代码   收藏代码
  1. package com.example.service07_aidlclient;  
  2. import android.app.Activity;  
  3. import android.content.ComponentName;  
  4. import android.content.Intent;  
  5. import android.content.ServiceConnection;  
  6. import android.os.Bundle;  
  7. import android.os.IBinder;  
  8. import android.os.RemoteException;  
  9. import android.util.Log;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13.   
  14. import com.example.service07_aidlservice.IMyService;  
  15. import com.example.service07_aidlservice.Product;  
  16.   
  17. public class MainActivity extends Activity implements OnClickListener {  
  18.     Button btnBind;//点击该按钮,启动远程Service  
  19.     Button  btnInvoke;//点击该按钮,远程调用Service  
  20.     IMyService mBinder; // 接口的一个引用  
  21.     private ServiceConnection mConn = new ServiceConnection() {  
  22.         @Override  
  23.         public void onServiceDisconnected(ComponentName name) {  
  24.         }  
  25.   
  26.         @Override  
  27.         public void onServiceConnected(ComponentName name, IBinder service) {  
  28.             /* 
  29.              * 获得另一个进程中的Service传递过来的对象service, 
  30.              * 用IMyService.Stub.asInterface方法转换该对象,这点与进程内的通信不同 
  31.              */  
  32.             mBinder = IMyService.Stub.asInterface(service);  
  33.             btnInvoke.setEnabled(true);  
  34.             Log.i("MainActivity""onServiceConnected....");  
  35.         }  
  36.     };  
  37.   
  38.     @Override  
  39.     protected void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.activity_main);  
  42.         btnBind = (Button) findViewById(R.id.btn_bind);  
  43.         btnInvoke = (Button) findViewById(R.id.btn_invoke);  
  44.         btnBind.setOnClickListener(this);  
  45.         btnInvoke.setOnClickListener(this);  
  46.     }  
  47.   
  48.     @Override  
  49.     public void onClick(View v) {  
  50.         Intent intent = new Intent();  
  51.         int btn = v.getId();  
  52.         switch (btn) {  
  53.         case R.id.btn_bind:  
  54. //Constant类中定义了要远程调用的服务  
  55. //public static final String ACTION_SERVICE = "com.example.service07.aidl";  
  56.             intent.setAction(Constant.ACTION_SERVICE);  
  57.             bindService(intent, mConn, BIND_AUTO_CREATE);  
  58.             break;  
  59.         case R.id.btn_invoke:  
  60.             try {  
  61.                 Product p = mBinder.getProduct();  
  62.                 Log.i("TAG", mBinder.getMap("country", p).toString());  
  63.                 Log.i("TAG", p.getName());  
  64.             } catch (RemoteException e) {  
  65.                 e.printStackTrace();  
  66.             }  
  67.             break;  
  68.         }  
  69.     }  
  70. }  

 

步骤8,先运行service服务端,再运行client客服端,得到结果如下:


 



 原文出处:http://lydia-fly.iteye.com/blog/2024638

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值