简单的AIDL通信

服务端的aidl和客户端的aidl的路径一定要一致!!
aidl文件:
// IBookManager.aidl
package com.example.chenxiaojiong.aidltest;

import com.example.chenxiaojiong.aidltest.Book;

interface IBookManager {

    List<Book> getBookList();
    void addBook(in Book book);
}
实现Parcelable接口的Book
// IBook.aidl
package com.example.chenxiaojiong.aidltest;

parcelable Book;

 
 

服务端的代码:

package com.example.chenxiaojiong.aidltest;

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

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

/**
 * Created by jiong on 2016/3/15 16:27.
 *
 * @描述 ${TODO}
 * @更新者 $Author$
 */
public class BookManagerService extends Service {

    private CopyOnWriteArrayList<Book> mBookList=new CopyOnWriteArrayList<Book>();

    @Override
    public void onCreate() {
        super.onCreate();
        mBookList.add(new Book(1, "Android"));
        mBookList.add(new Book(2,"IOS"));
    }
// 第一步:extends Services的时候就会自动要求你实现这个方法(用于监听客户端的链接请求)
    @Override
    public IBinder onBind(Intent intent) {

        return mIBinder;
    }
//第二步:一般是写AIDL文件(在里面暴露方法给客户端)
//第三步:在Service中实现AIDL的方法(暴露给客户端的方法)
    private Binder mIBinder = new IBookManager.Stub(){

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

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

    /**
     * 服务的死亡代理
     */
    private IBinder.DeathRecipient mDeathRecipient=new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {

        }
    };

}

面的服务使用到自定义的Parcelable接口,所以还需要写一个Book的类

package com.example.chenxiaojiong.aidltest;

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

/**
 * Created by jiong on 2016/3/15 15:43.
 *
 * @描述 ${TODO}
 * @更新者 $Author$
 */
public class Book implements Parcelable{

    public int bookId;
    public String bookName;

    public Book(int bookId, String bookName){

        this.bookId=bookId;
        this.bookName=bookName;
    }

    /**
     * 从序列化的对象中创建原始的对象
     */
    protected Book(Parcel in) {
        bookId=in.readInt();
        bookName=in.readString();
    }

    /**
     * 从序列化的对象中创建原始的对象
     */
    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

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

    /**
     * @return 返回当前对象的描述
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 实现对象的序列化
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(bookId);
        dest.writeString(bookName);
    }
}


服务端清单中Service的注册:
<service android:name=".BookManagerService"
                 android:exported="true"
                 android:process=":remote">
            <!-- android:process="name" name的值是随便取的 ,android:exported:是否允许被其它程序调用-->
            <intent-filter>
                <action android:name="jjj" />
            </intent-filter>
        </service>




客户端的代码:(直接使用bindServices,然后填写方法要求的参数,在其中的ServiceConnection 中获取AIDL的对象,并调用其方法

package com.example.chenxiaojiong.aidltest;

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.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private final String REMOTE_SERVICE_ACTION = "jjj";
    private Button mButton;
    private Intent mIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButton = (Button)findViewById(R.id.button);

        mIntent = new Intent();
        mIntent.setPackage(this.getPackageName());
        mIntent.setAction(REMOTE_SERVICE_ACTION);

        mIntent.setComponent(new ComponentName("com.example.chenxiaojiong.aidltest",
                "com.example.chenxiaojiong.aidltest.BookManagerService"));

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG,"服務起飛了nnnnnnnnnn");
                bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
            }
        });
    }




    private  ServiceConnection mServiceConnection= new ServiceConnection() {
        /**
         * service 就是服務端返回的AIDL對象
         * @param name
         * @param service
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            //获取AIDL的子类
            IBookManager iBookManager = IBookManager.Stub.asInterface(service);
            try {
                Log.e(TAG,"服務起飛了");
                List<Book> bookList = iBookManager.getBookList();
                Log.i(TAG,"query book list, list type:"+bookList.getClass().getCanonicalName());
                Log.i(TAG,"query book list:"+bookList.toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        unbindService(mServiceConnection);
        super.onDestroy();
    }
}

从Android 5.0之后 ,其中有个特性就是Service Intent  must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动。(需要添加:mIntent.setPackage(this.getPackageName());

还有一个是没报错也没有提示什么,加了下面的代码就可以了
 mIntent.setComponent(new ComponentName("com.example.chenxiaojiong.aidltest",
                "com.example.chenxiaojiong.aidltest.BookManagerService"));
还有就是上述的两点都不写的话,就会报java.lang.SecurityException: Not allowed to bind to service Intent


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值