Android Activity 與Service進行數(shù)據(jù)交互詳解
①從設計的角度來講:
Android的Activity的設計與Web頁面非常類似,從頁面的跳轉(zhuǎn)通過連接,以及從頁面的定位通過URL,從每個頁面的獨立封裝等方面都可以看出來,它主要負責與用戶進行交互。
Service則是在后臺運行,默默地為用戶提供功能,進行調(diào)度和統(tǒng)籌。如果一棵樹的地上部分是Activity的話,它龐大的根須就是Service。Android的服務組件沒有運行在獨立的進程或線程中,它和其他的組件一樣也在應用的主線程中運行,如果服務組件執(zhí)行比較耗時的操作就會導致主線程阻塞或者假死,從而無法響應用戶的操作。
因此,耗時的操作不要放在UI線程中,因為UI 5S,廣播10s就阻塞了,會引發(fā)ANR。
②從使用的角度來講:
Service不僅可以給Activity建立雙向連接,為Activity提供數(shù)據(jù)和功能支持,也可以單向接受Intent的請求,進行數(shù)據(jù)的分析處理和功能調(diào)度。
③從扮演的角色來講:
Activity的功能比較單一,主要就是顯示應用所具有的一些功能,幫助用戶與應用進行交互,像一個人的臉。而Service可能扮演功能調(diào)度者也能扮演功能提供者,從觸發(fā)器收集信息進行分析和處理,然后更新界面,修改數(shù)據(jù)或進行其他操作時是一個功能調(diào)度者,從輸入法的選擇考慮Service扮演的就是一個功能提供者。View組件是Android中用戶能夠?qū)崒嵲谠诳吹降牟糠?,如按鈕,輸入框等就是繼承自這個類,View只有裝入Activity這樣的容器中才有意義,而反過來Activity裝入了這些View后才能夠成功完成與用戶交互的任務,但是Service不需要這些花哨的東西,只需要默默地等待事件發(fā)生或者聽候差遣。
Android啟動Service有兩種方法,一種是startService,一種是bindService。生命周期如下:
執(zhí)行startService時,調(diào)用者如果沒有stopService,Service會一直在后臺運行。多次調(diào)用startService,該Service只能被創(chuàng)建一次,即該Service的onCreate方法只會被調(diào)用一次。但是每次調(diào)用startService,onStartCommand方法都會被調(diào)用。
執(zhí)行bindService時,調(diào)用者調(diào)用unbindService方法或者調(diào)用者Context不存在了(如Activity被finish了)。第一次執(zhí)行bindService時,onCreate和onBind方法會被調(diào)用,但是多次執(zhí)行bindService時,onCreate和onBind方法并不會被多次調(diào)用,即并不會多次創(chuàng)建服務和綁定服務。 多個組件可以同時綁定到該服務,但全部取消綁定后,該服務即會被銷毀。
既使用startService又使用bindService的情況,需要unbindService和stopService同時調(diào)用才會終止Service。
Activity與Service交互有兩種方法:一種是使用broadcast,另一種是使用bindService。本文只介紹bindService方法。
public class MsgService extends Service { public MsgService() { } /** * 進度條的最大值 */ public static final int MAX_PROGRESS = 100; /** * 進度條的進度值 */ private int progress = 0; /** * 增加get()方法,供Activity調(diào)用 * * @return 下載進度 */ public int getProgress() { return progress; } /** * 模擬下載任務,每秒鐘更新一次 */ public void startDownLoad(){ new Thread(new Runnable() { @Override public void run() { while(progress < MAX_PROGRESS){ progress += 5; //進度發(fā)生變化通知調(diào)用方 if(onProgressListener != null){ onProgressListener.onProgress(progress); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } public class MyBinder extends Binder { public MsgService getService() { return MsgService.this; } } public interface OnProgressListener { void onProgress(int progress); } /** * 更新進度的回調(diào)接口 */ private OnProgressListener onProgressListener; /** * 注冊回調(diào)接口的方法,供外部調(diào)用 * * @param onProgressListener */ public void setOnProgressListener(OnProgressListener onProgressListener) { this.onProgressListener = onProgressListener; } }
public class MainActivity extends Activity { private Button button19; private MsgService msgService; private int progress = 0; private ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnExec = (Button) findViewById(R.id.btnExec); button19 = (Button) findViewById(R.id.button19); mProgressBar = (ProgressBar) findViewById(R.id.progressBar); button19.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { msgService.startDownLoad(); } }); Intent intent = new Intent(this, MsgService.class); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { msgService = ((MsgService.MyBinder) iBinder).getService(); msgService.setOnProgressListener(new MsgService.OnProgressListener() { @Override public void onProgress(int progress) { mProgressBar.setProgress(progress); } }); } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onDestroy() { unbindService(mServiceConnection); super.onDestroy(); } }
例子中,MsgService模擬耗時的下載任務,MainActivity 綁定服務,通過注冊OnProgressListener回調(diào)獲取下載進度,更新進度條。
本例子Activity和Service是在同一個進程中,對于跨進程調(diào)用Service需要使用到AIDL技術(shù)。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Android檢測Activity或者Service是否運行的方法
- Android中Service和Activity相互通信示例代碼
- Android中Service與Activity之間通信的幾種方式
- Android Activity與Service通信(不同進程之間)詳解
- 淺談Android Activity與Service的交互方式
- Android使用Messenger實現(xiàn)service與activity交互
- Android實現(xiàn)Activity、Service與Broadcaster三大組件之間互相調(diào)用的方法詳解
- Android實現(xiàn)從activity中停止Service的方法
- Android中Service實時向Activity傳遞數(shù)據(jù)實例分析
- android使用service和activity獲取屏幕尺寸的方法
- 詳解Android Service與Activity之間通信的幾種方式
相關(guān)文章
超簡單Android集成華為HMS Scankit 掃碼SDK實現(xiàn)掃一掃二維碼
這篇文章主要介紹了超簡單Android集成華為HMS Scankit 掃碼SDK實現(xiàn)掃一掃二維碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03Android樣式的開發(fā):layer-list實例詳解
本文主要介紹Android樣式開發(fā)layer-list,這里整理了詳細的資料,及簡單示例代碼有興趣的小伙伴可以參考下2016-09-09Android短信驗證碼監(jiān)聽解決onChange多次調(diào)用的方法
本篇文章主要介紹了Android短信驗證碼監(jiān)聽解決onChange多次調(diào)用的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03Android通過AlarmManager類實現(xiàn)簡單鬧鐘功能
這篇文章主要為大家詳細介紹了Android通過AlarmManager類實現(xiàn)簡單鬧鐘功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06Android編程讀取Assets所有文件(遍歷每一個文件夾)并存入sdcard的方法
這篇文章主要介紹了Android編程讀取Assets所有文件(遍歷每一個文件夾)并存入sdcard的方法,涉及Android針對文件與目錄的遍歷及I/O操作相關(guān)技巧,需要的朋友可以參考下2016-02-02使用androidx BiometricPrompt實現(xiàn)指紋驗證功能
這篇文章主要介紹了使用androidx BiometricPrompt實現(xiàn)指紋驗證功能,對android指紋驗證相關(guān)知識感興趣的朋友跟隨小編一起看看吧2021-07-07Android中使用DialogFragment編寫對話框的實例教程
這篇文章主要介紹了Android中使用DialogFragment編寫對話框的實例教程,DialogFragment也是一種Fragment,因而管理生命周期時比較給力,需要的朋友可以參考下2016-04-04