Android菜鸟的成长笔记(21)——跨进程调用Service
来源:互联网 发布:gamemaker mac 编辑:程序博客网 时间:2024/05/16 13:43
我们都知道在Android中的每一个应用是一个进程,其实每一个应用就相当于Linux系统里面的一个用户,进程和进程之间的通信其实就相当于用户和用户之间的通信,为了实现这种跨进程通信,Android提供了AIDL Service ( Android Interface definition language).
与邦等本地Service不同的是,本地Service的onBind()方法会直接把IBinder对象本身传给客户端的ServiceConnection的onServiceConnected方法的第二个参数。但远程Service的onBind()方法只是将IBinder对象的代理传给客户端的ServiceConnection的onService Connected方法的第二个参数。
ALDL定义的特点:
1、AIDL定义接口的源码必须以.aidl结尾。
2、AIDL接口中用到数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使它们在同一个包中也需要导包。
下面来具体实现一个示例:
(1)定义AIDL接口(和Java接口非常类似)
- package com.example.testservice;
- interface ICat {
- String getColor();
- double getWeight();
- }
(2)定以好上面接口后保存,ADT工具会自动在gen.com.example.service目录下生成一个ICat.jar接口,在该接口中包含一个Stub内部类,该内部类实现了IBinder、ICat两个接口,这个Stub类将会作为远程Service的回调类——它实现了IBuilder接口,因此可作为Service的onBind()方法的返回值。这个Stub类就是一个代理类,同样可以实现IBinder的功能,并且还额外实现了ICat远程访问的功能。
自动生成的ICat.java接口
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D:\\adt-bundle-windows-x86-20130729\\eclipse\\workspace\\TestService\\src\\com\\example\\testservice\\ICat.aidl
- */
- package com.example.testservice;
- public interface ICat extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements
- com.example.testservice.ICat {
- private static final java.lang.String DESCRIPTOR = "com.example.testservice.ICat";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an com.example.testservice.ICat
- * interface, generating a proxy if needed.
- */
- public static com.example.testservice.ICat asInterface(
- android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof com.example.testservice.ICat))) {
- return ((com.example.testservice.ICat) iin);
- }
- return new com.example.testservice.ICat.Stub.Proxy(obj);
- }
- @Override
- public android.os.IBinder asBinder() {
- return this;
- }
- @Override
- public boolean onTransact(int code, android.os.Parcel data,
- android.os.Parcel reply, int flags)
- throws android.os.RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_getColor: {
- data.enforceInterface(DESCRIPTOR);
- java.lang.String _result = this.getColor();
- reply.writeNoException();
- reply.writeString(_result);
- return true;
- }
- case TRANSACTION_getWeight: {
- data.enforceInterface(DESCRIPTOR);
- double _result = this.getWeight();
- reply.writeNoException();
- reply.writeDouble(_result);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.example.testservice.ICat {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote) {
- mRemote = remote;
- }
- @Override
- public android.os.IBinder asBinder() {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
- @Override
- public java.lang.String getColor()
- throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- java.lang.String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getColor, _data, _reply,
- 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- @Override
- public double getWeight() throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- double _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getWeight, _data, _reply,
- 0);
- _reply.readException();
- _result = _reply.readDouble();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- }
- static final int TRANSACTION_getColor = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_getWeight = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
- }
- public java.lang.String getColor() throws android.os.RemoteException;
- public double getWeight() throws android.os.RemoteException;
- }
- package com.example.testservice;
- import java.util.Timer;
- import java.util.TimerTask;
- import com.example.testservice.ICat.Stub;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- public class AidlService extends Service{
- private CatBinder catBinder;
- Timer timer = new Timer();
- String[] colors = new String[]{
- "红色",
- "黄色",
- "黑色"
- };
- double[] weights = new double[]{
- 2.3,
- 3.1,
- 1.58
- };
- private String color;
- private double weight;
- @Override
- public IBinder onBind(Intent intent) {
- /*
- * 返回catBinder对象
- * 在绑定本地Service的情况下,该catBinder对象会直接传给客户端的
- * ServiceConnection对象的onServiceConnected方法的第二个参数;
- * 在绑定远程Service的情况下,只将catBinder对象的代理传给客户端的
- * ServiceConnection对象的onServiceConnected方法的第二个参数;
- */
- return catBinder;
- }
- //继承Stub,也就是实现了ICat接口,并实现了IBinder接口
- public class CatBinder extends Stub{
- @Override
- public String getColor() throws RemoteException {
- // TODO Auto-generated method stub
- return color;
- }
- @Override
- public double getWeight() throws RemoteException {
- // TODO Auto-generated method stub
- return weight;
- }
- }
- @Override
- public void onCreate() {
- super.onCreate();
- catBinder = new CatBinder();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- int rand = (int)(Math.random() * 3);
- color = colors[rand];
- weight = weights[rand];
- System.out.println("---------" + rand);
- }
- }, 0, 800);
- }
- }
(4)在AndroidMainfest.xml文件中配置该Service
- <service android:name=".AidlService">
- <intent-filter>
- <action android:name="com.example.testservice.action.AIDL_SERVICE"/>
- </intent-filter>
- </service>
(5)客户端访问AIDL Service
上面说过AIDL是定义在两个进程之间通信的一个接口,既然是一个通信协议,客户端同样需要前面定义的AIDL接口,所以第一步就是将AIDL文件复制到客户端应用中。
- package com.example.testservice;
- import android.app.Activity;
- import android.app.Service;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- public class AidlClient extends Activity{
- private ICat catService;
- private Button get;
- EditText color, weight;
- private ServiceConnection conn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- //获取远程Service的onBind方法返回的对象的代理
- catService = ICat.Stub.asInterface(service);
- }
- };
- protected void onCreate(android.os.Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- get = (Button)findViewById(R.id.get);
- color = (EditText)findViewById(R.id.color);
- weight = (EditText)findViewById(R.id.weight);
- //创建所需绑定的Service的Intent
- Intent intent = new Intent();
- intent.setAction("com.example.testservice.action.AIDL_SERVICE");
- bindService(intent, conn, Service.BIND_AUTO_CREATE);
- get.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- try {
- color.setText(catService.getColor());
- weight.setText(catService.getWeight() + "");
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- });
- };
- @Override
- protected void onDestroy() {
- super.onDestroy();
- //解除绑定
- this.unbindService(conn);
- }
- }
下一篇将介绍如何在进程之间传递复杂数据
0 0
- Android菜鸟的成长笔记(21)——跨进程调用Service
- Android菜鸟的成长笔记(21)——跨进程调用Service
- Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service
- Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service
- Android菜鸟的成长笔记(19)——Service的生命周期
- Android菜鸟的成长笔记(19)——Service的生命周期
- Android菜鸟的成长笔记(16)——Service简介
- Android菜鸟的成长笔记(18)——绑定本地Service并与之通信
- Android菜鸟的成长笔记(16)——Service简介
- Android菜鸟的成长笔记(18)——绑定本地Service并与之通信
- android基础笔记:服务(Service)跨进程调用Service(AIDL Service)
- 【Android】跨进程调用service
- android 跨进程Service调用
- Android菜鸟的成长笔记(20)——IntentService
- Android菜鸟的成长笔记(20)——IntentService
- Android的Service与BroadcastReceiver之二 跨进程调用Service(AIDL Service)
- Android学习笔记:Activity跨进程调用service。
- Android学习笔记----跨进程调用Service(AIDL)
- 死锁
- eclipse中如何将java源文件生成jar文件
- mongodb各种坑
- 错误四
- 面试经典(9)--求数组的逆序对
- Android菜鸟的成长笔记(21)——跨进程调用Service
- Linux文件查看命令
- HTML 网页图标 页头图标
- sql数据库学习系列一之SQL Server 数据库设计
- Mongoose使用案例–让JSON数据直接入库MongoDB
- Android菜鸟的成长笔记(22)——Android进程间传递复杂数据(AIDL)
- uboot中用到的linux命令
- jquery
- 探索推荐引擎内部的秘密-第 2 部分: 深入推荐引擎相关算法 - 协同过滤