AIDL详解

简单的AIDL实现

main文件夹下新建aidl包,注意包名一定要相同,定义接口
在这里插入图片描述

package com.example.aidldemo.aidl;
parcelable Book;
//~~~~~~~~~~~~~~~~~~~~~~~~
package com.example.aidldemo.aidl;
import  com.example.aidldemo.aidl.Book;//注意此处到导包
interface IBookManager {
    List<Book>getBookList();
    void addBook(in Book book);
}

同步一下,自动生成java文件
在这里插入图片描述

//服务端
public class BookMangerService extends Service {

    private static final String TAG = "BookMangerService";
    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);

       }
   };

    @Override
    public void onCreate() {
        super.onCreate();
        mBookList.add(new Book(1,"android"));
        mBookList.add(new Book(1,"ios"));
    }

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

}
//~~~~~~~~~~设为远程
<service
            android:name=".aidl.BookMangerService"
            android:process=":remote"/>



//客户端
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IBookManager bookManager=IBookManager.Stub.asInterface(service);
            try {
                List<Book> bookList = bookManager.getBookList();
                Log.e(TAG, "onServiceConnected: getBookList type"
                        +bookList.getClass().getCanonicalName() );
                Log.e(TAG, "onServiceConnected: "+bookList.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 intent = new Intent(this, BookMangerService.class);
        bindService(intent,conn,Context.BIND_AUTO_CREATE);
    }

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

    }
}
Binder机制详解

binder是android中的一个类,实现Ibinder接口,从IPC角度来说,Binder是Android中的一种跨进程通信方式,从Framework角度看,Binder是ServiceManager连接各种Manager(ActivityManager,WindowManager)的桥梁,从应用层来说,Binder是客户端和服务端通信的媒介,Binder底层细节复杂,暂时不深入研究。Android开发中,Binder主要用在Service中。包括AIDL和Messenger。Service很简单,不跨进程,binderService,Service的Onbinder里面返会一个binder对象,activity的onServiceConnect方法可以获取这个binder

所有可以在binder中传输的借口都要继承Interface接口 通过上面这个类可以了解binder的工作机制。
内部类Stub继承binder实现接口。当客户端服务端同一个进程时,方法调用不会走transact,跨进程时,就需要这个transact了,这个逻辑由Stub内部代理Proxy完成。下面说明几个主要方法

asInterface
将服务端binder对象转换成客户端aidl接口类型的对象。如果同一个进程,返回Stub,如果跨进程,返回系统封装后的Stub.proxy

asBinder
返回当前Binder对象
onTransact
Proxy#getBookList
Proxy#addBook

稍复杂的aidl实现&& aidl难点 线程相关

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int MESSAGE_BOOK_ARRIVED = 1;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mRemoteBookManager = IBookManager.Stub.asInterface(service);
            try {
                /**
                 * 难点,客户端调用远程服务的方法时,被调用的方法运行在服务端的binder线程池中,
                 * 同时,客户端线程挂起,如果服务端方法耗时,可能会导致anr,
                 * 服务端方法若耗时,也不必开线程
                 *
                 */
                List<Book> bookList = mRemoteBookManager.getBookList();
                Log.e(TAG, "onServiceConnected: getBookList type"
                        + bookList.getClass().getCanonicalName());
                Log.e(TAG, "onServiceConnected: " + bookList.toString());
                mRemoteBookManager.addBook(new Book(3, "android 进阶"));
                Log.e(TAG, "onServiceConnected: " + mRemoteBookManager.getBookList().toString());
                mRemoteBookManager.registerListener(mOnBookArrivedListener);
            } catch (RemoteException e) {
                e.printStackTrace();
            }


        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    IOnNewBookArrivedListener.Stub mOnBookArrivedListener =
            new IOnNewBookArrivedListener.Stub() {
                /**
                 * 服务端调用客户端listener方法,被调用方法运行在binder线程池中,
                 * 只不过是客户端的线程池,因此主线程更新ui
                 * 如果此方法耗时,要确保服务端运行在非ui线程
                 * @param newBook
                 * @throws RemoteException
                 */
                @Override
                public void onNewBookArrived(Book newBook) throws RemoteException {
                    mHandler.obtainMessage(MESSAGE_BOOK_ARRIVED, newBook);

                }
            };
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_BOOK_ARRIVED:
                    Log.e(TAG, "handleMessage: " + msg.obj);
                    break;
                default:
                    break;
            }
        }
    };
    private IBookManager mRemoteBookManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, BookMangerService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

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

    }
}
//~~~~~~~~~~~~~~~~~~~~
public class BookMangerService extends Service {

    private static final String TAG = "BookMangerService";

    private AtomicBoolean mIsServiceDestroyed = new AtomicBoolean(false);
    CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<Book>();
//    CopyOnWriteArrayList<IOnNewBookArrivedListener> mListenerList =
//            new CopyOnWriteArrayList<IOnNewBookArrivedListener>();
    /**
     * RemoteCallbackList内部有个map结构专门用来保存所有aidl回调,
     * key是IBinder,value是callback
     */
    private RemoteCallbackList<IOnNewBookArrivedListener> mListenerList =
            new RemoteCallbackList<IOnNewBookArrivedListener>();


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

        @Override
        public void registerListener(IOnNewBookArrivedListener listener) {
//            if (!mListenerList.contains(listener)) {
//                mListenerList.add(listener);
//            } else {
//                Log.e(TAG, "registerListener: alread exists");
//            }
            mListenerList.register(listener);
            final int N = mListenerList.beginBroadcast();
            Log.e(TAG, "registerListener:current size:" + N);

        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener) {
//            if (mListenerList.contains(listener)) {
//                mListenerList.remove(listener);
//                Log.e(TAG, "unregisterListener: unregister succeed");
//            } else {
//                Log.e(TAG, "unregisterListener: not found,can not unregister");
//            }
            boolean success = mListenerList.unregister(listener);

            if (success) {
                Log.d(TAG, "unregister success.");
            } else {
                Log.d(TAG, "not found, can not unregister.");
            }
            final int N = mListenerList.beginBroadcast();
            mListenerList.finishBroadcast();
            Log.d(TAG, "unregisterListener, current size:" + N);
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        mBookList.add(new Book(1, "android"));
        mBookList.add(new Book(1, "ios"));

    }

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

    private class ServiceWorker implements Runnable {

        @Override
        public void run() {
            while (!mIsServiceDestroyed.get()) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int bookId = mBookList.size() + 1;
                Book newBook = new Book(bookId, "new Book" + bookId);
                onNewBookArrived(newBook);
            }

        }
    }

    private void onNewBookArrived(Book newBook) {
        mBookList.add(newBook);
    }

    @Override
    public void onDestroy() {
        mIsServiceDestroyed.set(true);

        super.onDestroy();
    }
}


代码
https://github.com/gangjin1991/AndroidLearn/tree/master/aidldemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值