摘要:而使用綁定的方式啟動則可以實現之間的通信。下面就講述一下綁定實現本地通信的流程。單擊調用方法并且解除綁定。注意解除綁定事件只能執行一次,否則程序會崩潰。
寫作原因:跨進程通信的實現和理解是Android進階中重要的一環。下面博主分享IPC一些相關知識、操作及自己在學習IPC過程中的一些理解。
這一章是為下面的Messenger和AIDL的使用做準備,主要講解Android Service的綁定和Activity與本地Service之間通信相關知識。
簡介我們都知道啟動Service有兩種方式:startService()和bindService()。相比第一種方式,bindService()能夠更加靈活地實現與啟動端Activity的數據通信,第一種啟動方式啟動Activity與Service之間并沒有直接關聯,難以直接實現通信(當然了,使用BroadCast或者事件總線也是可以實現的)。而使用綁定的方式啟動Service則可以實現Service之間的通信。下面就講述一下綁定Service實現本地通信的流程。
以Activity調用Service中的方法為例,具體流程參考博主繪制的流程圖:
實例結合圖片我們來模擬開啟一個后臺執行更新功能為例來講解本地Service的綁定。
先分析一下該需求的場景:首先我們需要點擊Start按鈕開啟后臺更新數據,后臺將數據返回給Activity并在ProgressBar展示進度;當我們點擊Pause時后臺暫停更新;點擊Stop按鈕時關閉后臺。本例中也用到Service通過BroadCast向Activity傳遞數據。由于只是實例,對于線程操作一塊有一些bug,希望大家能夠幫忙指正。
Activity的布局如下:
Service實現先看看Service的實現,思路是這樣的:
先繼承Binder類創建MyBinder類,把MyBinder看做Service與Activity通信的代理人,所以在MyBinder內部中寫好方法間接調用Service中的方法以供Activity去調用(如本例中callPauseUpgrade())。關于IBinder對象的獲取除了直接重寫后面還有兩種方式,這里先不闡述了。在Service中我們開啟一個Thread,在這個Thread中模擬持續更新進度條直到isStop為False或者progress大于等于100時,然后將進度廣播出去,讓Activity接收到廣播進行進度條更新。Service中供Activity調用的方法實現暫停和停止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實現
下面是在客戶端實現與Service的通信代碼。主要思路是:先注冊廣播實現Service數據的返回;單擊Start按鈕時實現與Service的綁定,創建ServiceConnection對象實現ServiceConnection接口,分別回調綁定成功和失敗兩種情況下的邏輯。當成功時獲取MyBinder對象,并將設置的isBound值設為true;當失敗時將isBound設置為false。單擊Pause調用MyBinder對象的callPauseUpgrade()方法間接調用Service中的pauseUpgrade()方法。單擊Stop調用callStopUpgrade()方法并且解除綁定。注意解除綁定事件只能執行一次,否則程序會崩潰。具體實現并不難,主要是認真理解上面的流程圖即可。
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; } }; }總結
這篇文章是為下面的Messenger和AIDL跨進程通信做準備的,實際上個人感覺真正開發時可以使用EventBus或者RxJava取代這種同進程各個組件通信的問題,有興趣的讀者可以自行嘗試。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64925.html
摘要:中為何新增來作為主要的方式運行機制是怎樣的機制有什么優勢運行機制是怎樣的基于通信模式,除了端和端,還有兩角色一起合作完成進程間通信功能。 目錄介紹 2.0.0.1 什么是Binder?為什么要使用Binder?Binder中是如何進行線程管理的?總結binder講的是什么? 2.0.0.2 Android中進程和線程的關系?什么是IPC?為何需要進行IPC?多進程通信可能會出現什么問...
閱讀 2111·2021-11-24 10:28
閱讀 1117·2021-10-12 10:12
閱讀 3337·2021-09-22 15:21
閱讀 679·2021-08-30 09:44
閱讀 1895·2021-07-23 11:20
閱讀 1147·2019-08-30 15:56
閱讀 1751·2019-08-30 15:44
閱讀 1483·2019-08-30 13:55