Android之AIDL服务

本文详细介绍了Android中AIDL(Android Interface Definition Language)服务的使用,用于实现跨进程通讯。通过AIDL,开发者可以定义接口并在客户端和服务端之间进行通信。主要步骤包括创建aidl文件定义接口、生成Java接口代码、实现服务类、配置AndroidManifest.xml。文章还通过一个实例展示了AIDL服务的创建过程,并比较了AIDL与其他跨进程通讯方式如Activity、ContentProvider、Broadcast的区别和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


AIDL服务

       服务(Service)是android系统中非常重要的组件。Service可以脱离应用程序运行。也就是说,应用程序只起到一个启动Service的作用。一但Service被启动,就算应用程序关闭,Service仍然会在后台运行。

       android系统中的Service主要有两个作用:后台运行和跨进程通讯。后台运行就不用说了,当Service启动后,就可以在Service对象中 运行相应的业务代码,而这一切用户并不会察觉。而跨进程通讯是这一节的主题。如果想让应用程序可以跨进程通讯,就要使用我们这节讲的AIDL服 务,AIDL的全称是Android Interface Definition Language,也就是说,AIDL实际上是一种接口定义语言。通过这种语言定义接口后,Eclipse插件(ODT)会自动生成相应的Java代码接 口代码。下面来看一下编写一个AIDL服务的基本步骤。

1.  在Eclipse工程的package目录中建立一个扩展名为aidl的文件。package目录就是Java类所在的目录。该文件的语法类似于Java代码。aidl文件中定义的是AIDL服务的接口。这个接口需要在调用AIDL服务的程序中访问。
2.  如果aidl文件的内容是正确的,Eclipse插件会自动生成一个Java接口文件(*.java)。
3.  建立一个服务类(Service的子类)。
4.  实现由aidl文件生成的Java接口。
5.  在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签的android:name属性值就是客户端要引用该服务的ID,也就是Intent类构造方法的参数值。

      现在我们来编写一个AIDL服务,首先建立一个android工程:aidlservice。在aidlservice工程中有一个Main类,在Main类所有的目录建立一个IMyService.aidl文件,内容如下:

 package  net.blogjava.mobile.aidlservice;  
interface  IMyService  
{  
    String getValue();  //  为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法   
} 
    package net.blogjava.mobile.aidlservice;  
    interface IMyService  
    {  
        String getValue();  //  为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法  
    }  
在保存IMyService.aidl文件后,ODT会在gen目录下产生一个IMyService.java文件,读者可以不必管这个文件中的内容,也 不需要修改该文件的内容。这个文件是由ODT自动维护的,只要修改了IMyService.aidl文件的内容,IMyService.java文件的内 容就会随之改变。

        然后建立一个MyService类,该类是Service的子类,代码如下:

    package  net.blogjava.mobile.aidlservice;  
    ... ...  
    public  class  MyService extends  Service  
    {  
        //  IMyService.Stub类是根据IMyService.aidl文件生成的类,该类中包含了接口方法(getValue)   
        public  class  MyServiceImpl extends  IMyService.Stub  
        {  
            @Override   
            public  String getValue() throws  RemoteException  
            {  
                return  "从AIDL服务获得的值." ;  
            }  
        }  
        @Override   
        public  IBinder onBind(Intent intent)  
    {          
    //  该方法必须返回MyServiceImpl类的对象实例   
            return  new  MyServiceImpl();  
        }  
    }  
    package net.blogjava.mobile.aidlservice;  
    ... ...  
    public class MyService extends Service  
    {  
        //  IMyService.Stub类是根据IMyService.aidl文件生成的类,该类中包含了接口方法(getValue)  
        public class MyServiceImpl extends IMyService.Stub  
        {  
            @Override  
            public String getValue() throws RemoteException  
            {  
                return "从AIDL服务获得的值.";  
            }  
        }  
        @Override  
        public IBinder onBind(Intent intent)  
    {          
    //  该方法必须返回MyServiceImpl类的对象实例  
            return new MyServiceImpl();  
        }  
    }  
最后需要在AndroidManifest.xml文件中配置MyService类,代码如下:

    <!--  注册服务 -->  
    <service android:name=".MyService" >  
        <intent-filter>  
            <!--  指定调用AIDL服务的ID  -->  
            <action android:name="net.blogjava.mobile.aidlservice.IMyService"  />  
        </intent-filter>  
    </service>  

    <!--  注册服务 -->  
    <service android:name=".MyService">  
        <intent-filter>  
            <!--  指定调用AIDL服务的ID  -->  
            <action android:name="net.blogjava.mobile.aidlservice.IMyService" />  
        </intent-filter>  
    </service>  
下面来看看如何调用这个AIDL服务。首先建立一个android工程:aidlclient。然后将aidlservice工程中自动生成的 IMyService.java文件复制到aidlclient工程中。在调用AIDL服务之前需要先使用bindService方法绑定AIDL服务。 bindService方法需要一个ServiceConnection对象。ServiceConnection有一个 onServiceConnected方法,当成功绑定AIDL服务且,该方法被调用。并通过service参数返回AIDL服务对象。下面是调用 AIDL服务的完成代码。

 package  net.blogjava.mobile.aidlclient;  
... ...  
public  class  Main extends  Activity implements  OnClickListener  
{  
private  IMyService myService = null ;  
//  创建ServiceConnection对象   
    private  ServiceConnection serviceConnection = new  ServiceConnection()  
    {  
        @Override   
        public  void  onServiceConnected(ComponentName name, IBinder service)  
        {  
            // 获得AIDL服务对象   
            myService = IMyService.Stub.asInterface(service);  
            try   
            {  
                //  调用AIDL服务对象中的getValue方法,并以对话框中显示该方法的返回值   
                new  AlertDialog.Builder(Main.this ).setMessage(  
                        myService.getValue()).setPositiveButton("确定" , null )  
                        .show();  
            }  
            catch  (Exception e)  
            {  
            }  
        }  
        @Override   
        public  void  onServiceDisconnected(ComponentName name)  
        {  
        }  
    };  
    @Override   
    public  void  onClick(View view)  
{  
    //  绑定AIDL服务   
        bindService(new  Intent("net.blogjava.mobile.aidlservice.IMyService" ),  
                serviceConnection, Context.BIND_AUTO_CREATE);  
    }  
    ... ...  
} 
    package net.blogjava.mobile.aidlclient;  
    ... ...  
    public class Main extends Activity implements OnClickListener  
    {  
    private IMyService myService = null;  
    //  创建ServiceConnection对象  
        private ServiceConnection serviceConnection = new ServiceConnection()  
        {  
            @Override  
            public void onServiceConnected(ComponentName name, IBinder service)  
            {  
                // 获得AIDL服务对象  
                myService = IMyService.Stub.asInterface(service);  
                try  
                {  
                    //  调用AIDL服务对象中的getValue方法,并以对话框中显示该方法的返回值  
                    new AlertDialog.Builder(Main.this).setMessage(  
                            myService.getValue()).setPositiveButton("确定", null)  
                            .show();  
                }  
                catch (Exception e)  
                {  
                }  
            }  
            @Override  
            public void onServiceDisconnected(ComponentName name)  
            {  
            }  
        };  
        @Override  
        public void onClick(View view)  
    {  
        //  绑定AIDL服务  
            bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService"),  
                    serviceConnection, Context.BIND_AUTO_CREATE);  
        }  
        ... ...  
    }  

在编写AIDL服务和客户端时要注意如下两点:

1.  AIDL服务中的onBind方法必须返回AIDL接口对象(MyServiceImpl对象)。该对象也是onServiceConnected事件方法的第2个参数值。
2.  bindService方法的第1个参数是Intent对象,该对象构造方法的参数需要指定AIDL服务的ID,也就是在 AndroidManifest.xml文件中<service>标签的<action>子标签的android:name属性 的值。

 现在先运行aidlservice程序,以便安装AIDL服务,然后运行aidlclient程序,并单击按钮,会显示如图11所示的对话框。对话框中的信息就是AIDL服务接口中getValue方法的返回值。

总结 
      本文介绍了4种跨进程通讯的方式:Activity、ContentProvider、Broadcast和AIDL Service。其中Activity可以跨进程调用其他应用程序的Activity;ContentProvider可以访问其他应用程序返回的 Cursor对象;Broadcast采用的是被动接收的方法,也就是说,客户端只能接收广播数据,而不能向发送广播的程序发送信息。AIDL Service可以将程序中的某个接口公开,这样在其他的应用程序中就可以象访问本地对象一样访问AIDL服务对象了。这4种跨进程通讯的方式可以应用在 不同的场合,例如,在需要显示可视化的界面时可以用Activity,需要返回记录集时可以用ContentProvider。至于在应用程序中具体要用 到哪一种或几种方式进行跨进程通讯,读者可以根据实际情况进行选择。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值