Android AIDL基础用法

一、概述
本文将讲述基本的aidl使用方法实现进程间通信,后续将讲述如果将自己的写的服务加入到系统服务中,提供给系统应用使用,典型案例应用锁。

二、编写思路
1、服务器端定义aidl以及传递的bean类,然后编写具体aidl实现类,新建服务在onBind方法中返回实现的binder类对象。
2、客户端需要新建服务端定义的aidl以及相关类,建议服务器端把aidl以及相关的类定义在一个包中。客户端要使用时以及拷贝过来。
三、编码具体实现demo

1、服务器端*
1、在main下新建一个aidi文件夹,在新建一个包,然后定义Book.java类,实现Parcelable接口,代码如下

package com.android.topwise.applock;

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

public class Book implements Parcelable {

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

    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];
        }
    };

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

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

2、新建aidl接口,我在这里新建的是IBookManager.aidl,其中定义俩个方法,代码如下,记到导入需要使用的实体类,并创建对应的aidl文件,我这里使用Book类,定义Book.aidl。

// IBookManager.aidl
package com.android.topwise.applock;

// Declare any non-default types here with import statements

import com.android.topwise.applock.Book;

interface IBookManager {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    void addBook(in Book  book);
    List<Book> getBookList();
}

3、Book.aidl代码如下

// Book.aidl
package com.android.topwise.applock;
parcelable Book;

4、服务端还需要写一个服务类,并写一个binder实现类,代码如下

package com.android.topwise.applock;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class BookService extends Service {


    private List<Book> books  = new ArrayList<>();

    public BookService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
         return  new MyBookManager();
    }
    private final class  MyBookManager extends IBookManager.Stub
    {


        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

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

        @Override
        public List<Book> getBookList() throws RemoteException {


            return books;
        }
    }
}

2、客户端
1、直接复制服务器端aidl的包,然后直接去绑定服务器端的服务获取接口对象。代码如下

package com.android.topwise.applock;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.id_tv_show)
    TextView idTvShow;
    @Bind(R.id.id_btn_add)
    Button idBtnAdd;
    @Bind(R.id.id_btn_get)
    Button idBtnGet;
    private IBookManager mIBookManager;


    private ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIBookManager = IBookManager.Stub.asInterface(iBinder);

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        Intent intent = new Intent("com.android.topwise.applock.IBookManager");
        Intent intentHide = createExplicitFromImplicitIntent(this, intent);
        bindService(intentHide, mServiceConnection, Context.BIND_AUTO_CREATE);

    }

   //此方法可以将返回一个可以隐式启动服务的Intent
    public Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);

        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }


    @OnClick({R.id.id_btn_add, R.id.id_btn_get})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.id_btn_add:
                Book book = new Book(0, "第一行代码");
                try {
                    mIBookManager.addBook(book);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.id_btn_get:

                try {
                    List<Book> books = mIBookManager.getBookList();
                    if (books.size() > 0) {
                        idTvShow.setText(books.get(0).bookName);
                    }

                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}

四、aidl的基本用法就以上所示,相信很多读者都和我一样,在最开始接触的时候会困惑,为什么要如此麻烦,其实aidl是为了实现进程间多线程的情况,在平时的日常应用开发中很少需要进程间通信,但是在系统开发中就非常重要了,因为binder是android 实现进程间通信特有的方式,SystemServer进程中的服务都是用binder的方式进行通信的,例如ActivityManagerServce等,在app开发中Content.getSystemService(“”)的方法获取到系统服务端的实例就是binder进程间通信,只是这里的进程是SystemServer进程与我们的APP进程进行通信而已。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值