成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Android IPC機(jī)制(一)——綁定Service實(shí)現(xiàn)本地通信

GitCafe / 1391人閱讀

摘要:而使用綁定的方式啟動則可以實(shí)現(xiàn)之間的通信。下面就講述一下綁定實(shí)現(xiàn)本地通信的流程。單擊調(diào)用方法并且解除綁定。注意解除綁定事件只能執(zhí)行一次,否則程序會崩潰。

寫作原因:跨進(jìn)程通信的實(shí)現(xiàn)和理解是Android進(jìn)階中重要的一環(huán)。下面博主分享IPC一些相關(guān)知識、操作及自己在學(xué)習(xí)IPC過程中的一些理解。

這一章是為下面的Messenger和AIDL的使用做準(zhǔn)備,主要講解Android Service的綁定和Activity與本地Service之間通信相關(guān)知識。

簡介

我們都知道啟動Service有兩種方式:startService()和bindService()。相比第一種方式,bindService()能夠更加靈活地實(shí)現(xiàn)與啟動端Activity的數(shù)據(jù)通信,第一種啟動方式啟動Activity與Service之間并沒有直接關(guān)聯(lián),難以直接實(shí)現(xiàn)通信(當(dāng)然了,使用BroadCast或者事件總線也是可以實(shí)現(xiàn)的)。而使用綁定的方式啟動Service則可以實(shí)現(xiàn)Service之間的通信。下面就講述一下綁定Service實(shí)現(xiàn)本地通信的流程。

以Activity調(diào)用Service中的方法為例,具體流程參考博主繪制的流程圖:

實(shí)例

結(jié)合圖片我們來模擬開啟一個后臺執(zhí)行更新功能為例來講解本地Service的綁定。

先分析一下該需求的場景:首先我們需要點(diǎn)擊Start按鈕開啟后臺更新數(shù)據(jù),后臺將數(shù)據(jù)返回給Activity并在ProgressBar展示進(jìn)度;當(dāng)我們點(diǎn)擊Pause時后臺暫停更新;點(diǎn)擊Stop按鈕時關(guān)閉后臺。本例中也用到Service通過BroadCast向Activity傳遞數(shù)據(jù)。由于只是實(shí)例,對于線程操作一塊有一些bug,希望大家能夠幫忙指正。

Activity的布局如下:

Service實(shí)現(xiàn)

先看看Service的實(shí)現(xiàn),思路是這樣的:

先繼承Binder類創(chuàng)建MyBinder類,把MyBinder看做Service與Activity通信的代理人,所以在MyBinder內(nèi)部中寫好方法間接調(diào)用Service中的方法以供Activity去調(diào)用(如本例中callPauseUpgrade())。關(guān)于IBinder對象的獲取除了直接重寫后面還有兩種方式,這里先不闡述了。在Service中我們開啟一個Thread,在這個Thread中模擬持續(xù)更新進(jìn)度條直到isStop為False或者progress大于等于100時,然后將進(jìn)度廣播出去,讓Activity接收到廣播進(jìn)行進(jìn)度條更新。Service中供Activity調(diào)用的方法實(shí)現(xiàn)暫停和停止Thread的功能,具體過程參照代碼。

public class UpgradeService extends Service {
    private Thread thread;
    private Intent intent;
    private int progress;
    private Boolean isStop;
    public class MyBinder extends Binder{
        public void callPauseUpgrade(){
            pauseUpgrade();
        }

        public void callStopUpgrade() {
            stopUpgrade();
        }
    }

    private void stopUpgrade() {
        progress = 0;
        isStop = false;
        intent.putExtra("progress",progress);
        sendBroadcast(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        progress = 0;
        isStop = true;
        intent = new Intent();
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while(isStop){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    progress = progress +5;
                    intent.putExtra("progress",progress);
                    intent.setAction("UPGRADE_ACTION");
                    sendBroadcast(intent);
                    if(progress>=100) break;
                }

            }
        });
        thread.start();
    }

    private void pauseUpgrade() {
        //TODO:Pause the upgrade
        Toast.makeText(getApplicationContext(),"暫停",Toast.LENGTH_SHORT).show();
        isStop = false;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
}
Activity實(shí)現(xiàn)

下面是在客戶端實(shí)現(xiàn)與Service的通信代碼。主要思路是:先注冊廣播實(shí)現(xiàn)Service數(shù)據(jù)的返回;單擊Start按鈕時實(shí)現(xiàn)與Service的綁定,創(chuàng)建ServiceConnection對象實(shí)現(xiàn)ServiceConnection接口,分別回調(diào)綁定成功和失敗兩種情況下的邏輯。當(dāng)成功時獲取MyBinder對象,并將設(shè)置的isBound值設(shè)為true;當(dāng)失敗時將isBound設(shè)置為false。單擊Pause調(diào)用MyBinder對象的callPauseUpgrade()方法間接調(diào)用Service中的pauseUpgrade()方法。單擊Stop調(diào)用callStopUpgrade()方法并且解除綁定。注意解除綁定事件只能執(zhí)行一次,否則程序會崩潰。具體實(shí)現(xiàn)并不難,主要是認(rèn)真理解上面的流程圖即可。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button mBtStart;
    private Button mBtStop;
    private Button mBtPause;
    private ProgressBar mPbProgress;
    private UpgradeService.MyBinder myBinder;
    private boolean isBound;
    private UpgradeReceiver upgradeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("UPGRADE_ACTION");
        upgradeReceiver = new UpgradeReceiver();
        registerReceiver(upgradeReceiver,intentFilter);
        initView();
        initEvent();

    }
    public class UpgradeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            mPbProgress.setProgress(intent.getIntExtra("progress",0));
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(upgradeReceiver);
    }

    private void initEvent() {
        mBtPause.setOnClickListener(this);
        mBtStart.setOnClickListener(this);
        mBtStop.setOnClickListener(this);
    }

    private void initView() {
        mBtPause = (Button) findViewById(R.id.bt_pause);
        mBtStart = (Button) findViewById(R.id.bt_start);
        mBtStop = (Button) findViewById(R.id.bt_stop);
        mPbProgress = (ProgressBar) findViewById(R.id.pb_progress);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.bt_pause:
                if(isBound&&myBinder!=null){
                    myBinder.callPauseUpgrade();
                }
                break;
            case R.id.bt_start:
                bindService(new Intent(MainActivity.this,UpgradeService.class),conn,BIND_AUTO_CREATE);
                break;
            case R.id.bt_stop:
                if(isBound) {
                    myBinder.callStopUpgrade();
                    unbindService(conn);
                    isBound = false;
                }
                break;
        }
    }

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if(service != null){
                myBinder = (UpgradeService.MyBinder) service;
                isBound = true;
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBound = false;
        }
    };
}
總結(jié)

這篇文章是為下面的Messenger和AIDL跨進(jìn)程通信做準(zhǔn)備的,實(shí)際上個人感覺真正開發(fā)時可以使用EventBus或者RxJava取代這種同進(jìn)程各個組件通信的問題,有興趣的讀者可以自行嘗試。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64925.html

相關(guān)文章

  • 02.AndroidIPC機(jī)制問題

    摘要:中為何新增來作為主要的方式運(yùn)行機(jī)制是怎樣的機(jī)制有什么優(yōu)勢運(yùn)行機(jī)制是怎樣的基于通信模式,除了端和端,還有兩角色一起合作完成進(jìn)程間通信功能。 目錄介紹 2.0.0.1 什么是Binder?為什么要使用Binder?Binder中是如何進(jìn)行線程管理的?總結(jié)binder講的是什么? 2.0.0.2 Android中進(jìn)程和線程的關(guān)系?什么是IPC?為何需要進(jìn)行IPC?多進(jìn)程通信可能會出現(xiàn)什么問...

    Donne 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<