AIDL

2.service的种类,
由于adroid的独特的线程模型,service被同一个apk调用和不同apk调用原理是不同的,因此分成以下两种:
(1). 本地服务(Local Service):说白了就是在同一个apk内被调用。
(2). 远程服务(Remote Sercie):被另外一个apk调用。 AIDL来实现

AIDL: Android Interface definition language的,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

 ---------------------------------------------------------------------------

服务端:

//ICat.aidl 
package
org.crazyit.service; interface ICat { String getColor(); double getWeight(); }

 

//ICat.java 这个文件是依据ICat.aidl自动生成的,不需要进行任何修改
package org.crazyit.service;

public interface ICat extends android.os.IInterface {
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements
            org.crazyit.service.ICat {
        private static final java.lang.String DESCRIPTOR = "org.crazyit.service.ICat";

        /** Construct the stub at attach it to the interface. */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an org.crazyit.service.ICat interface,
         * generating a proxy if needed.
         */
        public static org.crazyit.service.ICat asInterface(
                android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof org.crazyit.service.ICat))) {
                return ((org.crazyit.service.ICat) iin);
            }
            return new org.crazyit.service.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 org.crazyit.service.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 org.crazyit.service;

import java.util.Timer;
import java.util.TimerTask;

import org.crazyit.service.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;

    public class CatBinder extends Stub {
        @Override
        public String getColor() throws RemoteException {
            return color;
        }

        @Override
        public double getWeight() throws RemoteException {
            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];
            }
        }, 0, 800);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return catBinder;
    }

    @Override
    public void onDestroy() {
        timer.cancel();
    }
}

 AidlService这个类不会被显示实例化,而是通过org.crazyit.aidl.action.AIDL_SERVICE来标识它的。绑定服务的时候依据含有这个action的Intent来识别AidlService

//AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.crazyit.service"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <!-- 定义一个Service组件 -->
        <service android:name=".AidlService" >
            <intent-filter>
                <action android:name="org.crazyit.aidl.action.AIDL_SERVICE" />
            </intent-filter>
        </service>
    </application>
</manifest> 

 

-----------------------------------------------

客户端:

//ICat.aidl
package org.crazyit.service;

interface ICat
{
    String getColor();
    double getWeight();
}

 

public class AidlClient extends Activity {
    private ICat catService;
    private Button get;
    EditText color, weight;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            catService = ICat.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            catService = null;
        }
    };

    @Override
    public void onCreate(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);

        Intent intent = new Intent();
        intent.setAction("org.crazyit.aidl.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
    public void onDestroy() {
        super.onDestroy();
        this.unbindService(conn);
    }
}

 

运行的时候,先将服务端(这个是没有界面的)安装起来,然后再运行客户端。

posted @ 2015-03-16 13:22  牧 天  阅读(204)  评论(0)    收藏  举报