Android之AIDL服务

举报
chenyu 发表于 2021/07/27 00:47:07 2021/07/27
【摘要】 AIDL服务        服务(Service)是android系统中非常重要的组件。Service可以脱离应用程序运行。也就是说,应用程序只起到一个启动Service的作用。一但Service被启动,就算应用程序关闭,Service仍然会在后台运行。     &n...


AIDL服务

       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文件,内容如下:


  
  1. package net.blogjava.mobile.aidlservice;
  2. interface IMyService
  3. {
  4. String getValue(); // 为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法
  5. }

  
  1. package net.blogjava.mobile.aidlservice;
  2. interface IMyService
  3. {
  4. String getValue(); // 为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法
  5. }

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


  
  1. package net.blogjava.mobile.aidlservice;
  2. ... ...
  3. public class MyService extends Service
  4. {
  5. // IMyService.Stub类是根据IMyService.aidl文件生成的类,该类中包含了接口方法(getValue)
  6. public class MyServiceImpl extends IMyService.Stub
  7. {
  8. @Override
  9. public String getValue() throws RemoteException
  10. {
  11. return "从AIDL服务获得的值." ;
  12. }
  13. }
  14. @Override
  15. public IBinder onBind(Intent intent)
  16. {
  17. // 该方法必须返回MyServiceImpl类的对象实例
  18. return new MyServiceImpl();
  19. }
  20. }

  
  1. package net.blogjava.mobile.aidlservice;
  2. ... ...
  3. public class MyService extends Service
  4. {
  5. // IMyService.Stub类是根据IMyService.aidl文件生成的类,该类中包含了接口方法(getValue)
  6. public class MyServiceImpl extends IMyService.Stub
  7. {
  8. @Override
  9. public String getValue() throws RemoteException
  10. {
  11. return "从AIDL服务获得的值.";
  12. }
  13. }
  14. @Override
  15. public IBinder onBind(Intent intent)
  16. {
  17. // 该方法必须返回MyServiceImpl类的对象实例
  18. return new MyServiceImpl();
  19. }
  20. }


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


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


  
  1. package net.blogjava.mobile.aidlclient;
  2. ... ...
  3. public class Main extends Activity implements OnClickListener
  4. {
  5. private IMyService myService = null ;
  6. // 创建ServiceConnection对象
  7. private ServiceConnection serviceConnection = new ServiceConnection()
  8. {
  9. @Override
  10. public void onServiceConnected(ComponentName name, IBinder service)
  11. {
  12. // 获得AIDL服务对象
  13. myService = IMyService.Stub.asInterface(service);
  14. try
  15. {
  16. // 调用AIDL服务对象中的getValue方法,并以对话框中显示该方法的返回值
  17. new AlertDialog.Builder(Main.this ).setMessage(
  18. myService.getValue()).setPositiveButton("确定" , null )
  19. .show();
  20. }
  21. catch (Exception e)
  22. {
  23. }
  24. }
  25. @Override
  26. public void onServiceDisconnected(ComponentName name)
  27. {
  28. }
  29. };
  30. @Override
  31. public void onClick(View view)
  32. {
  33. // 绑定AIDL服务
  34. bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService" ),
  35. serviceConnection, Context.BIND_AUTO_CREATE);
  36. }
  37. ... ...
  38. }

  
  1. package net.blogjava.mobile.aidlclient;
  2. ... ...
  3. public class Main extends Activity implements OnClickListener
  4. {
  5. private IMyService myService = null;
  6. // 创建ServiceConnection对象
  7. private ServiceConnection serviceConnection = new ServiceConnection()
  8. {
  9. @Override
  10. public void onServiceConnected(ComponentName name, IBinder service)
  11. {
  12. // 获得AIDL服务对象
  13. myService = IMyService.Stub.asInterface(service);
  14. try
  15. {
  16. // 调用AIDL服务对象中的getValue方法,并以对话框中显示该方法的返回值
  17. new AlertDialog.Builder(Main.this).setMessage(
  18. myService.getValue()).setPositiveButton("确定", null)
  19. .show();
  20. }
  21. catch (Exception e)
  22. {
  23. }
  24. }
  25. @Override
  26. public void onServiceDisconnected(ComponentName name)
  27. {
  28. }
  29. };
  30. @Override
  31. public void onClick(View view)
  32. {
  33. // 绑定AIDL服务
  34. bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService"),
  35. serviceConnection, Context.BIND_AUTO_CREATE);
  36. }
  37. ... ...
  38. }

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。至于在应用程序中具体要用 到哪一种或几种方式进行跨进程通讯,读者可以根据实际情况进行选择。








文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/50816873

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。