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>

服务端的结构如下:

java 跨进程通讯框架 java跨进程调用_android



步骤6:客户端的编写:新建客户端项目,把IMyService.aidl,Product.aidl,Product.java 连同包一起拷贝到Client的src目录

客户端结构:

java 跨进程通讯框架 java跨进程调用_service_02

步骤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。。。。。