AIDL 服务只支持有限的数据类型,如果用AIDL服务传递一些复杂的数据就需要做更一步处理
现在我们来实现android.os.Parcelable 接口的类.
实现Parcelable接口的类,除了要建立一个实现Parcelable 接口的类外, 还需要为这个类单独建立一个aidl 文件, 并使用parcelable 关键字进行定义。
因为是跨进程的通信协议,需要创建两个项目,一个项目是后台程序,一个是启动该后台服务的客户端,通过启动这两个项目来演示2个进程间的通信。
步骤1:创建Service项目,将该项目中的Activity类删除,新建类Product.java,实现Parcelable接口。代码如下:
package com.example.aidl2;
import android.os.Parcel;
import android.os.Parcelable;
public class Product implements Parcelable{
private int id;
private String name;
private float price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Product() {
}
public Product(Parcel in) {
id = in.readInt();
name = in.readString();
price = in.readFloat();
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeInt(id);
dest.writeString(name);
dest.writeFloat(price);
}
public static final Parcelable.Creator<Product> CREATOR=new Creator<Product>() {
@Override
public Product[] newArray(int size) {
// TODO Auto-generated method stub
return new Product[size];
}
@Override
public Product createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new Product(source);
}
};
}
步骤2 :为这个类单独建立一个aidl 文件, 并使用parcelable 关键字进行定义,Product.aidl代码如下:
注意: parcelable 首字母是小写
package com.example.aidl2;
parcelable Product;
步骤3:新建IMyService.aidl文件,代码如下:
package com.example.aidl2;
import com.example.aidl2.Product;//必须导包
interface IMyService{
Map getMap(in String country,in Product product);
Product getProduct();
}
步骤4:新建包结构com.example.aidlService2,自定义MyService.java类,该类继承Service类
Java代码:
package com.example.service2;
import java.util.HashMap;
import java.util.Map;
import com.example.aidl2.IMyService;
import com.example.aidl2.Product;
import android.R.integer;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyService extends Service{
private MyBinder myBinder;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return myBinder;
}
private class MyBinder extends IMyService.Stub{
@Override
public Map getMap(String country, Product product) throws RemoteException {
// TODO Auto-generated method stub
Map map=new HashMap<String,String>();
map.put("id", product.getId());
map.put("name", product.getName());
map.put("price", product.getPrice());
map.put("country", country);
//
map.put("product", product);
return map;
}
@Override
public Product getProduct() throws RemoteException {
// TODO Auto-generated method stub
Product product = new Product();
product.setId(1234);
product.setName("奔驰");
product.setPrice(300000);
return product;
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
myBinder=new MyBinder();
}
}
步骤5:在AndroidManifest.xml中注册Service,并去掉MianActivity的配置。
<service android:name="com.example.service2.MyService"
android:process=":remote"
android:exported="true">
<intent-filter >
<action android:name="com.service2"/>
</intent-filter>
</service>
服务端的结构如下:
步骤6:客户端的编写:新建客户端项目,把IMyService.aidl,Product.aidl,Product.java 连同包一起拷贝到Client的src目录
客户端结构:
步骤7:编写MainActivity.java 和 xml布局文件
Java代码:
package com.example.client_aidl2;
import android.util.Log;
import java.util.Iterator;
import java.util.Map;
import com.example.aidl2.IMyService;
import com.example.aidl2.Product;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
private Button btBinder;
private Button btGetdata;
private TextView tv;
private boolean isBinder=false;
IMyService mBinder;
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mBinder=IMyService.Stub.asInterface(service);
Log.i("MainActivity", "onServiceConnected()");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btBinder=(Button) findViewById(R.id.bt_binder);
btGetdata=(Button) findViewById(R.id.bt_get_data);
tv=(TextView) findViewById(R.id.tv);
btBinder.setOnClickListener(this);
btGetdata.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
switch (v.getId()) {
case R.id .bt_binder:
intent.setAction("com.service2");
intent.setPackage("com.example.aidl2");
bindService(intent, conn, BIND_AUTO_CREATE);
isBinder=true;
break;
case R.id .bt_get_data:
try {
if(isBinder){
Product p=mBinder.getProduct();
String info=mBinder.getMap("中国", p).toString();
//Log.i("TAG",mBinder.getMap("country", p).toString());
//Log.i("TAG", p.getName());
tv.setText(info);
}else{
Toast.makeText(this, "请先点击BINDER按钮绑定服务", Toast.LENGTH_SHORT).show();
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}
客户端activity_main.xml的代码如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.client_aidl2.MainActivity" >
<Button
android:id="@+id/bt_binder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Binder"/>
<Button
android:id="@+id/bt_get_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/bt_binder"
android:layout_centerInParent="true"
android:text="getData"/>
<TextView android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/bt_binder"
android:layout_centerInParent="true"
android:paddingBottom="15dp"
/>
</RelativeLayout>
over。。。。。