AIDL sample

AIDL
1.編寫一個AIDL
如:
package com.elfylin; 
interface IMyService { 
    String getValue();
}

AIDL和java一樣,要保證路徑和包名一樣。
不過不是每一個java對象,AIDL都支持,不需要聲明的有int、boolean、String、CharSequence,在List、Map、Parcelabels也只能包含基本類型。
2.通過ADT生成一個java文件。
如下:
package com.elfylin;
public interface IMyService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements com.elfylin.IMyService
    {
        private static final java.lang.String DESCRIPTOR = "com.elfylin.IMyService";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
            this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an com.elfylin.IMyService interface,
         * generating a proxy if needed.
         */
        public static com.elfylin.IMyService asInterface(android.os.IBinder obj)
        {
            if ((obj==null)) {
                return null;
            }
            android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
            if (((iin!=null)&&(iin instanceof com.elfylin.IMyService))) {
                return ((com.elfylin.IMyService)iin);
            }
            return new com.elfylin.IMyService.Stub.Proxy(obj);
        }
        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_getValue:
                {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _result = this.getValue();
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }
        private static class Proxy implements com.elfylin.IMyService
        {
            private android.os.IBinder mRemote;
            Proxy(android.os.IBinder remote)
            {
                mRemote = remote;
            }
            public android.os.IBinder asBinder()
            {
                return mRemote;
            }
            public java.lang.String getInterfaceDescriptor()
            {
                return DESCRIPTOR;
            }
            public java.lang.String getValue() 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_getValue, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }
        static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }
    public java.lang.String getValue() throws android.os.RemoteException;
}

裏面有如下信息
a. IMyService繼承IInterface,因此有asBinder這個函數
b 裏面的內部類Stub
Stub繼承了Binder,實現了IMyService。
實現了IInterface的asBinder(),實現了IMyService的getValue()函數。
增加了com.elfylin.IMyService asInterface(android.os.IBinder obj)
重載了Binder的 onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
c 內部類 Proxy
Proxy實現了com.elfylin.IMyService
裏面有一個內部變量private android.os.IBinder mRemote;
增加了android.os.IBinder asBinder()
java.lang.String getInterfaceDescriptor()
實現了getValue()


3.Service實現
a 編寫一個Service的Android工程作爲外殼。類名MyService繼承Service。
b 在裏面些一個自己的類MyServiceImpl繼承IMyService.Stub
重寫裏面的getValue,變成自己的實現。
c 重寫這個Service外殼的onBinder函數,返回繼承於IMyService.Stub MyServiceImpl的實例。
package com.elfylin;
import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.os.RemoteException;

public class MyService extends Service { 
    public class MyServiceImpl extends IMyService.Stub { 
        @Override 
        public String getValue() throws RemoteException { 
        return "'test"; 
        } 
    } 
    @Override 
    public IBinder onBind(Intent intent) { 
    return new MyServiceImpl(); 
    }
}



4、客戶端實現
a 要把服務器端的AIDL和生成的java文件一起拷貝到客戶端的src目錄
b 寫一個ServiceConnection的回調實例,重載其
public void onServiceConnected(ComponentName name, IBinder service)
public void onServiceDisconnected(ComponentName name)
這兩個回調函數
並且在public void onServiceConnected(ComponentName name, IBinder service)中
IMyService myService = IMyService.Stub.asInterface(service)
以此來獲取AIDL中的proxy對象
private ServiceConnection serviceConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
        myService = IMyService.Stub.asInterface(service); 
        btnInvokeAIDLService.setEnabled(true); 
    } 
    @Override 
        public void onServiceDisconnected(ComponentName name) { 
    } 
}; 


c 在onCreate或者其他事件觸發中,連接遠程服務,並且傳入剛纔的回調
bindService(new Intent("com.elfy.aidl.IMyService"), serviceConnection
d 在所有需要服務的地方通過myService來調用即可
bindService(new Intent("net.blogjava.mobile.aidl.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE); 

call process:
client:bindService(new Intent,serviceConnection).
service:IBinder onBinder(Intent intent)
    return MyServiceImpl
    call ServiceConnection onServiceConnected(MyServiceImpl);
client: 
    onServiceConnected(service)
    myService = IMyservice.Stub.asInterface(service)
    IMyservice.Stub.asInterface
        return new com.elfylin.IMyService.Stub.Proxy(obj)
    myService = com.elfylin.IMyService.Stub.Proxy
    myService.getValue
    com.elfylin.IMyService.Stub.Proxy.getValue
    mRemote.transact(Stub.TRANSACTION_getValue, _data, _reply, 0);
    service.transact(Stub.TRANSACTION_getValue, _data, _reply, 0)
server
    MyServiceImpl.onTransact
    IMyService.Stub.onTransact
    IMyService.Stub.getValue
    MyServiceImpl.getValue
    reply.writeString(_result);
client
    _result = _reply.readString();


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章