首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

建立AIDL服务的方法(2)

2012-09-19 
建立AIDL服务的步骤(2)8.4.2建立AIDL服务的步骤(2)在编写上面代码时应注意如下两点:使用bindService方法来

建立AIDL服务的步骤(2)
8.4.2  建立AIDL服务的步骤(2)

在编写上面代码时应注意如下两点:

使用bindService方法来绑定AIDL服务。其中需要使用Intent对象指定AIDL服务的ID,也就是<action>标签中android:name属性的值。

在绑定时需要一个ServiceConnection对象。创建ServiceConnection对象的过程中如果绑定成功,系统会调用onServiceConnected方法,通过该方法的service参数值可获得AIDL服务对象。

首先运行AIDL服务程序,然后运行客户端程序,单击【绑定AIDL服务】按钮,如果绑定成功,【调用AIDL服务】按钮会变为可选状态,单击这个按钮,会输出getValue方法的返回值,如图8.26所示。

实例53:传递复杂数据的AIDL服务

AIDL服务工程目录:src\ch08\ch08_complextypeaidl

客户端程序工程目录:src\ch08\ch08_complextypeaidlclient

AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据就需要做更一步处理。AIDL服务支持的数据类型如下:

Java的简单类型(int、char、boolean等)。不需要导入(import)。

String和CharSequence。不需要导入(import)。

List和Map。但要注意,List和Map对象的元素类型必须是AIDL服务支持的数据类型。不需要导入(import)。

AIDL自动生成的接口。需要导入(import)。

实现android.os.Parcelable接口的类。需要导入(import)。

其中后两种数据类型需要使用import进行导入,将在本章的后面详细介绍。

传递不需要import的数据类型的值的方式相同。传递一个需要import的数据类型的值(例如,实现android.os.Parcelable接口的类)的步骤略显复杂。除了要建立一个实现android.os.Parcelable接口的类外,还需要为这个类单独建立一个aidl文件,并使用parcelable关键字进行定义。具体的实现步骤如下:

(1)建立一个IMyService.aidl文件,并输入如下代码:
package net.blogjava.mobile.complex.type.aidl; 
import net.blogjava.mobile.complex.type.aidl.Product; 
interface IMyService   
{   
    Map getMap(in String country, in Product product); 
    Product getProduct();      
}

在编写上面代码时要注意如下两点:

Product是一个实现android.os.Parcelable接口的类,需要使用import导入这个类。

如果方法的类型是非简单类型,例如,String、List或自定义的类,需要使用in、out或inout修饰。其中in表示这个值被客户端设置;out表示这个值被服务端设置;inout表示这个值既被客户端设置,又被服务端设置。

(2)编写Product类。该类是用于传递的数据类型,代码如下:
package net.blogjava.mobile.complex.type.aidl; 

import android.os.Parcel; 
import android.os.Parcelable; 

public class Product implements Parcelable 

    private int id; 
    private String name; 
    private float price; 
    public static final Parcelable.Creator<Product>
CREATOR = new Parcelable.Creator<Product>() 
    { 
        public Product createFromParcel(Parcel in) 
        { 
            return new Product(in); 
        } 

        public Product[] newArray(int size) 
        { 
            return new Product[size];  
        } 
    }; 
    public Product() 
    { 
    } 
    private Product(Parcel in) 
    { 
        readFromParcel(in); 
    } 
    @Override 
    public int describeContents() 
    { 
        return 0; 
    } 
    public void readFromParcel(Parcel in) 
    { 
        id = in.readInt(); 
        name = in.readString(); 
        price = in.readFloat(); 
    } 
    @Override 
    public void writeToParcel(Parcel dest, int flags) 
    { 
        dest.writeInt(id); 
        dest.writeString(name); 
        dest.writeFloat(price); 
    } 
    //  此处省略了属性的getter和setter方法 
    ... ... 
}

在编写Product类时应注意如下3点:

Product类必须实现android.os.Parcelable接口。该接口用于序列化对象。在Android中之所以使用Pacelable接口序列化,而不是java.io.Serializable接口,是因为Google在开发Android时发现Serializable序列化的效率并不高,因此,特意提供了一个Parcelable接口来序列化对象。

在Product类中必须有一个静态常量,常量名必须是CREATOR,而且CREATOR常量的数据类型必须是Parcelable.Creator。

在writeToParcel方法中需要将要序列化的值写入Parcel对象。

(3)建立一个Product.aidl文件,并输入如下内容:
parcelable Product;


(4)编写一个MyService类,代码如下:
package net.blogjava.mobile.complex.type.aidl; 

import java.util.HashMap; 
import java.util.Map; 
import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.os.RemoteException; 
//  AIDL服务类 
public class MyService extends Service 
{  
    public class MyServiceImpl extends IMyService.Stub 
    { 
        @Override 
        public Product getProduct() throws RemoteException 
        { 
            Product product = new Product(); 
            product.setId(1234); 
            product.setName("汽车"); 
            product.setPrice(31000);  
            return product; 
        } 
        @Override 
        public Map getMap(String country, Product
product) throws RemoteException 
        { 
            Map map = new HashMap<String, String>(); 
            map.put("country", country); 
            map.put("id", product.getId()); 
            map.put("name", product.getName()); 
            map.put("price", product.getPrice()); 
            map.put("product", product); 
            return map; 
        } 
    } 
    @Override 
    public IBinder onBind(Intent intent) 
    {         
        return new MyServiceImpl(); 
    } 
}

(5)在AndroidManifest.xml文件中配置MyService类,代码如下:
<service android:name=".MyService" >
    <intent-filter>  
        <action android:name="net.blogjava.
mobile.complex.type.aidl.IMyService" />
    </intent-filter>
</service>

在客户端调用AIDL服务的方法与实例52介绍的方法相同,首先将IMyService.java和Product.java文件复制到客户端工程(ch08_complextypeaidlclient),然后绑定AIDL服务,并获得AIDL服务对象,最后调用AIDL服务中的方法。完整的客户端代码如下:
package net.blogjava.mobile; 

import net.blogjava.mobile.complex.type.aidl.IMyService; 
import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class Main extends Activity implements OnClickListener 

    private IMyService myService = null; 
    private Button btnInvokeAIDLService; 
    private Button btnBindAIDLService; 
    private TextView textView; 
    private ServiceConnection serviceConnection = new ServiceConnection() 
    { 
        @Override 
        public void onServiceConnected(ComponentName name, IBinder service) 
        { 
              //  获得AIDL服务对象 
            myService = IMyService.Stub.asInterface(service); 
            btnInvokeAIDLService.setEnabled(true); 
        } 
        @Override 
        public void onServiceDisconnected(ComponentName name) 
        { 
        } 
    }; 
    @Override 
    public void onClick(View view) 
    { 
        switch (view.getId()) 
        { 
            case R.id.btnBindAIDLService: 
                   //  绑定AIDL服务 
                bindService(new Intent("net.blogjava.
mobile.complex.type.aidl.IMyService"), 
                        serviceConnection, Context.BIND_AUTO_CREATE); 
                break; 
            case R.id.btnInvokeAIDLService: 
                try 
                { 
                    String s = ""; 
                       //  调用AIDL服务中的方法 
                    s = "Product.id = " + myService.
getProduct().getId() + "\n"; 
                    s += "Product.name = " + myService.
getProduct().getName() + "\n"; 
                    s += "Product.price = " + myService.
getProduct().getPrice() + "\n";             
                    s += myService.getMap("China",
myService.getProduct()).toString(); 
                    textView.setText(s); 
                } 
                catch (Exception e) 
                { 
                } 
                break; 
        } 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService); 
        btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService); 
        btnInvokeAIDLService.setEnabled(false); 
        textView = (TextView) findViewById(R.id.textview); 
        btnInvokeAIDLService.setOnClickListener(this); 
        btnBindAIDLService.setOnClickListener(this); 
    } 
}

首先运行服务端程序,然后运行客户端程序,单击【绑定AIDL服务】按钮,待成功绑定后,单击【调用AIDL服务】按钮,会输出如图8.27所示的内容。

热点排行