AIDL简单实现(1)

1、服务端

服务端首先要创建一个Service用来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给的客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可

2、客户端

客户端首先要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,接着就可以调用AIDL中的方法了。

3、AIDL接口创建

AIDL支持如下接口类型:

除去short以外的基本数据类型
String和CharSequence
List:只支持ArrayList,且内部的数据必须能够被AIDL支持
Map:只支持HashMap,里面的key和value必须都被AIDL支持
Parcelable:所有实现了这个接口的类(android提供的序列化接口)
AIDL接口文件本身

所以我们可以创建如下接口文件:

package com.wscq.myaidl.aidl;
import com.wscq.myaidl.aidl.Book;
interface IBookManager {
    List<Book> getBookList();
    void addBook(in Book book);
}  

其中book类不是AIDL支持的接口类型,所以需要自定义一个Book类,实现Parcelable接口

package com.wscq.myaidl.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {
    public int bookId;
    public String bookName;

    public Book(int bookId, String bookName) {
        this.bookId = bookId;
        this.bookName = bookName;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(bookId);
        dest.writeString(bookName);
    }

    public static final Parcelable.Creator<Book> CREATOR = new parcelable.Creator<Book>() {
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    private Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
    }

    @Override
    public String toString() {
        return "Book [bookId=" + bookId + ", bookName=" + bookName + "]";
    }

}
注意在每一个实现了Parcelable的接口类,都需要创建相应的AIDL文件去声明,如下代码所示:
package com.wscq.myaidl.aidl;
parcelable Book;  

建议所有的AIDL文件都放到一个文件夹下,因为客户端和服务端都会用到此文件,这样可以方便复制

4、远程服务端Service的实现

package com.wscq.myaidl;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import com.wscq.myaidl.aidl.Book;
import com.wscq.myaidl.aidl.IBookManager;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

public class BookManagerService extends Service {
    private static final String TAG = "BMS";
    /** 使用这个list的原因是他可以进行自动的线程同步,类似的还有ConcurrentHashMap */
    private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<Book>();
    private Binder mBinder = new IBookManager.Stub() {

        @Override
        public List<Book> getBookList() throws RemoteException {
            return mBookList;
        }

        @Override
        public void addBook(Book book) throws RemoteException {
            mBookList.add(book);
        }
    };

    public void onCreate() {
        super.onCreate();
        mBookList.add(new Book(1, "Android"));
        mBookList.add(new Book(2, "Ios"));
    }

    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

需要在AndroidManfist中进行如下注册:
这里为了方便测试,所以Service和Activity处于一个程序中。所以需要用’android:process=”:remote” ‘这个标签,来让Service单独运行在一个线程中,这样可以模拟IPC通讯。

        <service
            android:name="com.wscq.myaidl.BookManagerService"
            android:process=":remote" >
        </service>  

5、客户端的代码实现

package com.wscq.myaidl;
import java.util.List;
import com.wscq.myaidl.aidl.Book;
import com.wscq.myaidl.aidl.IBookManager;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class BookManagerActivity extends Activity {
    private static final String TAG = "BookManagerActivity";
    private ServiceConnection mConnection = new ServiceConnection() {
        // 服务连接后
        @Override
        /**
         * 服务连接以后执行此方法
         */
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 通过Binder来传递bookManager
            IBookManager bookManager = IBookManager.Stub.asInterface(service);
            try {
                List<Book> list = bookManager.getBookList();
                // 获取返回的类型
                // query book list, list type:java.util.ArrayList
                Log.i(TAG, "query book list, list type:" + list.getClass().getCanonicalName());
                // 获取书名
                // quert book list: [Book [bookId=1, bookName=Android], Book
                // [bookId=2, bookName=Ios]]
                Log.i(TAG, "quert book list: " + list.toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 通过intent来连接远程服务端,5.0以后必须使用显式意图,也就是必须使用全类名
        Intent intent = new Intent(this, BookManagerService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConnection);
    }
}
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值