android AIDL 語言用法

來源:互聯網
上載者:User

標籤:查看   creat   hat   androi   返回   implicit   bin   技術   auto   

跨進程通訊可以用AIDL語言

這裡講述下如何使用AIDL語言進行跨進程通訊

文章參考 《設計模式》一書

demo結構參考

主要的檔案類有:IBankAidl.aidl

java檔案:AidlBankBinder,BackActivity(應該是BankActivity寫錯了),BankService(繼承自Service,服務類)

IBankAidl.aidl檔案 這裡AIdl的使用對包位置有要求,所以我就把包名放出來了

package finishdemo.arcturis.binderandserviceandaidl.binder;// Declare any non-default types here with import statementsinterface IBankAidl {    /**     * 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);   /**     * 開戶     * @param name 戶主名     * @param password 密碼     * @return 開戶資訊     */    String openAccount(String name,String password);    /**     * 存錢     * @param money     * @param account     * @return     */    String saveMoney(int money,String account);    /**     * 取錢     * @param money     * @param account     * @param password     * @return     */    String takeMoney(int money,String account,String password);    /**     * 銷戶     * @param account     * @param password     * @return     */    String closeAccount(String account,String password);}

AidlBankBinder檔案 繼承自IBankAidl的Stub類,然後重寫並實現Aidl內的方法,這裡是類比一個銀行的操作

public class AidlBankBinder extends IBankAidl.Stub {    @Override    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {    }    @Override    public String openAccount(String name, String password) {        return name+"開戶成功!帳號為:"+ UUID.randomUUID().toString();    }    @Override    public String saveMoney(int money, String account) {        return "賬戶:"+account + "存入"+ money + "單位:人民幣";    }    @Override    public String takeMoney(int money, String account, String password) {        return "賬戶:"+account + "支取"+ money + "單位:人民幣";    }    @Override    public String closeAccount(String account, String password) {        return account + "銷戶成功";    }}

BankService檔案 返回一個AidlBankBinder 

public class BankService extends Service {    @Nullable    @Override    public IBinder onBind(Intent intent) {        //單進程寫法//        return new BankBinder();        //不同進程AIDL 通訊寫法        return new AidlBankBinder();    }}

接下來在Activity中使用 BackActivity方法

public class BackActivity extends AppCompatActivity implements View.OnClickListener {//    private BankBinder mBankBinder;    private IBankAidl mBankBinder;    private TextView tvMsg;    private Context context;    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //同一進程寫法//            mBankBinder = (BankBinder) service;            //不同進程寫法            mBankBinder = IBankAidl.Stub.asInterface(service);        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        context = this;        tvMsg = (TextView) findViewById(R.id.tv_msg);        Intent intent = new Intent();        intent.setAction("actionname.aidl.bank.BankService");        //這裡遇到一個問題,如果你直接使用intent 這個意圖去開啟服務的話就會報        //Android Service Intent must be explicit 意思是服務必須要顯示的調用,這個是5.0之後新的規定        //這個 createExplicitFromImplicitIntent 可以將隱性調用變成顯性調用        Intent intent1  = new Intent(createExplicitFromImplicitIntent(context,intent));        bindService(intent1,conn,BIND_AUTO_CREATE);        initBtn(R.id.btn_aidl_bank_close);        initBtn(R.id.btn_aidl_bank_open);        initBtn(R.id.btn_aidl_bank_save);        initBtn(R.id.btn_aidl_bank_take);    }    @Override    protected void onDestroy() {        super.onDestroy();        unbindService(conn);    }    private void initBtn(int resID){        Button b = (Button) findViewById(resID);        b.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.btn_aidl_bank_open:                //這個RemoteException 是 AIDL跨進程通訊的用法必須加上的異常捕獲                try {                    tvMsg.setText(mBankBinder.openAccount("BigAss","123456"));                }catch (RemoteException e){                    e.printStackTrace();                }                break;            case R.id.btn_aidl_bank_save:                try {                    tvMsg.setText(mBankBinder.saveMoney(8888888,"bigAss123"));                }catch (RemoteException e){                    e.printStackTrace();                }                break;            case R.id.btn_aidl_bank_take:                try {                    tvMsg.setText(mBankBinder.takeMoney(520,"bigAss123","123456"));                }catch (RemoteException e){                    e.printStackTrace();                }                break;            case R.id.btn_aidl_bank_close:                try {                    tvMsg.setText(mBankBinder.closeAccount("bigAss123","123456"));                }catch (RemoteException e){                    e.printStackTrace();                }                break;        }    }    /***     * Android L (lollipop, API 21) introduced a new problem when trying to invoke implicit intent,     * "java.lang.IllegalArgumentException: Service Intent must be explicit"     *     * If you are using an implicit intent, and know only 1 target would answer this intent,     * This method will help you turn the implicit intent into the explicit form.     *     * Inspired from SO answer: http://stackoverflow.com/a/26318757/1446466     * @param context     * @param implicitIntent - The original implicit intent     * @return Explicit Intent created from the implicit original intent     */    public static 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;    }}

主要思路是用隱式的方法啟動一個服務,然後調用Aidl執行個體類的方法即可,具體的Aidl語言在BuildApp之後在

這裡即可查看 內部是他實現進程間資料轉送所做的轉化代碼,有興趣可以看下

 

android AIDL 語言用法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.