AIDL终极篇之AIDL架构设计

来源:互联网 发布:淘宝运费险怎么退邮费 编辑:程序博客网 时间:2024/06/12 02:09

本技术博文计划分为三个系列:
一、AIDL的基础,http://blog.csdn.net/wangqiubo2010/article/details/78601666。
二、AIDL之Messenger,http://blog.csdn.net/wangqiubo2010/article/details/78615047.。
三、AIDL终极篇之AIDL架构设计。


本文为AIDL设计的终极篇,AIDL架构设计。

在设计这个架构设计之前,思考一个问题:随着项目越来越大,如果请求的服务器中的服务类型越来越多,按照普通的设计有两种办法。
第一,服务器所执行的方法全部放在一个或者少量几个类中,这里有个问题就是,多种不同类型的请求全部塞在一个类中,并且类越来越庞大,这和职责分离完全背离。

第二,建立无数个service,每个service实现一种类型服务,也即是每种类型都生成一个IBinder,并且会有无数个链接,这样的设计服务器迟早会被拖垮。


针对以上问题,现在就是对AIDL的设计架构进行改进。

AIDL新设计架构图如下:
这里写图片描述

对本架构进行解析:

服务端架构解析:
1、IBinder1、IBinder2、IBinder3…,这些都是根据各种功能类型实现的每个Stub。

2、AIDLPoolService(IBinder管理器)。
AIDLPoolService其实就是客户端需要连接的服务,但是本服务提供给客户端的IBinder其实是一个IBinder管理器,本管理器只有一个方法queryBinder,这个方法就是根据ID来分发查询所需要类型的IBinder,入上面的IBinder1、IBinder2等。

服务器这样的设计就能解决以上2个问题。
第一,IBinder1、IBinder2、IBinder3…,无论你有多少种类型的功能,都可以无限增加,既解决了职责分离问题,又实现了动态增加功能。
第二,本架构连接服务器只会请求一次,请求成功之后,后续只要传一个IBinder的ID就可以查询到所需求的IBinder,则客户端获取到之后就可以直接调用服务器的方法。

客户端架构解析:
1、client1、client2、client3……,就是客户端每个功能模块了。
2、AIDLPoolClient,封装了对Service的连接,有一个IBinder查询器,client1、client2、client3……只要传个ID过去就可以直接获取到所需求的IBinder。


以上架构代码如下:

//AIDLPoolService(IBinder管理器)。package com.example.myservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.support.annotation.Nullable;/** * Created by wangqiubo on 2017/5/17. */public class AidlPoolService extends Service{    @Nullable    @Override    public IBinder onBind(Intent intent) {        return aidlPool;    }    private static IBinder aidlPool = new AidlPoolImpl();}
//AidlPoolImpl.javapackage com.example.myservice;import android.os.Debug;import android.os.IBinder;import android.os.RemoteException;import com.example.wangqiubo.myaidl.IAidlPool;/** * Created by wangqiubo on 2017/5/17. */public class AidlPoolImpl extends IAidlPool.Stub {    public static final int BOOK_BINDER_ID = 0;    public static final int USER_BINDER_ID = 1;    IBinder mBinder = null;    @Override    public IBinder queryBinder(int binderId) throws RemoteException {//        Debug.waitForDebugger();        switch(binderId){            case BOOK_BINDER_ID:                mBinder = new BookImpl();                break;            case USER_BINDER_ID:                mBinder = new UserImpl();                break;        }        return mBinder;    }}
//BookImpl.java(AIDL的实现)package com.example.myservice;import android.os.RemoteException;import com.example.wangqiubo.myaidl.Book;import com.example.wangqiubo.myaidl.IBookCallBackInterface;import com.example.wangqiubo.myaidl.IBooksAidlInterface;import java.util.ArrayList;import java.util.List;/** * Created by wangqiubo on 2017/5/17. */public class BookImpl extends IBooksAidlInterface.Stub {    List<Book> books = new ArrayList<>();    @Override    public List<Book> getBookList() throws RemoteException {        return books;    }    @Override    public void addBook(Book book) throws RemoteException {        books.add(book);    }    @Override    public void registerBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {    }    @Override    public void unregisterBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {    }}
//UserImpl.java,AIDL的实现。package com.example.myservice;import android.os.RemoteException;import com.example.wangqiubo.myaidl.IUserAidlInterface;import com.example.wangqiubo.myaidl.User;import java.util.ArrayList;import java.util.List;public class UserImpl extends IUserAidlInterface.Stub {    List<User> userList = new ArrayList<>();    @Override    public void addUser(User user) throws RemoteException {        userList.add(user);    }    @Override    public List<User> getUsers() throws RemoteException {        return userList;    }}

以下是客户端代码。

package com.example.wangqiubo.myapplication;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Binder;import android.os.Debug;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import com.example.wangqiubo.myaidl.IAidlPool;/** * Created by wangqiubo on 2017/5/17. */public class AidlPool {    public static final int BOOK_BINDER_ID = 0;    public static final int USER_BINDER_ID = 1;    private IAidlPool aidlPoolInterface = null;    private IBinder mBinder = null;    public AidlPool(Context context){        Intent intent = new Intent();        ComponentName componentName = new ComponentName("com.example.myservice","com.example.myservice.AidlPoolService");        intent.setComponent(componentName);        context.bindService(intent, connection, Context.BIND_AUTO_CREATE);    }    public IBinder queryBinder(int binderId) throws RemoteException {//        switch(binderId){//            case BOOK_BINDER_ID://                mBinder = aidlPoolInterface.queryBinder(binderId)//                break;//            case USER_BINDER_ID:////                break;//        }        //Debug.waitForDebugger();        Log.d("aidlPool:", " queryBinder");        if (null == aidlPoolInterface)            return null;        mBinder = aidlPoolInterface.queryBinder(binderId);        return mBinder;    }    public IAidlPool getAidlPoolInterface(){        return aidlPoolInterface;    }    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.d("aidlPool", " ServiceConnection");            aidlPoolInterface = IAidlPool.Stub.asInterface(service);            if (null != aidlPoolInterface)                Log.d("aidlPool:", "aidlPoolInterface is not null");        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };}
package com.example.wangqiubo.myapplication;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.RemoteException;import android.view.View;import android.widget.Button;import android.widget.ListView;import com.example.wangqiubo.myaidl.Book;import com.example.wangqiubo.myaidl.IBooksAidlInterface;import java.util.List;/** * Created by wangqiubo on 2017/5/17. */public class AidlPoolActivity extends Activity implements View.OnClickListener{    private IBooksAidlInterface booksAidlInterface = null;    private ListView mListView = null;    private Button addBook = null;    private Button queryBinder = null;    private MyHandler mHandler = null;    private AidlPool mAidlPool = null;    private CustomBaseAdapter customBaseAdapter = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.aidl_pool);        mHandler = new MyHandler();        mListView = (ListView) findViewById(R.id.my_list_view);        customBaseAdapter = new CustomBaseAdapter(this);        mListView.setAdapter(customBaseAdapter);        addBook = (Button)findViewById(R.id.update);        addBook.setOnClickListener(this);        queryBinder = (Button)findViewById(R.id.query);        queryBinder.setOnClickListener(this);        mAidlPool = new AidlPool(this);    }    @Override    protected void onStart() {        super.onStart();    }    @Override    protected void onRestart() {        super.onRestart();    }    @Override    protected void onResume() {        super.onResume();    }    @Override    protected void onPause() {        super.onPause();    }    @Override    protected void onStop() {        super.onStop();    }    @Override    protected void onDestroy() {        super.onDestroy();    }    private static final int ADD_BOOK_CODE = 0;    @Override    public void onClick(View v) {        if (v.getId() == R.id.update){            new Thread(new Runnable() {                @Override                public void run() {                    Book book = new Book("乔布斯", "名人传", "1");                    try {                        booksAidlInterface.addBook(book);                        book = new Book("雷军", "名人传", "2");                        booksAidlInterface.addBook(book);                        book = new Book("柳传志", "名人传", "3");                        booksAidlInterface.addBook(book);                        List<Book> books = booksAidlInterface.getBookList();                        customBaseAdapter.setBookDatas(books);                        Message msg = mHandler.obtainMessage();                        msg.what = ADD_BOOK_CODE;                        msg.sendToTarget();                    } catch (RemoteException e) {                        e.printStackTrace();                    }                }            }).start();        }else if (v.getId() == R.id.query){            try {                IBinder binder = mAidlPool.queryBinder(AidlPool.BOOK_BINDER_ID);                if (null != binder){                    booksAidlInterface = IBooksAidlInterface.Stub.asInterface(binder);                }            } catch (RemoteException e) {                e.printStackTrace();            }        }    }    private class MyHandler extends Handler{        @Override        public void handleMessage(Message msg) {            switch (msg.what){                case ADD_BOOK_CODE:                    customBaseAdapter.notifyDataSetChanged();                    break;                default:                    break;            }            super.handleMessage(msg);        }    }}
原创粉丝点击