Android Activity 與Service進(jìn)行數(shù)據(jù)交互詳解
①從設(shè)計的角度來講:
Android的Activity的設(shè)計與Web頁面非常類似,從頁面的跳轉(zhuǎn)通過連接,以及從頁面的定位通過URL,從每個頁面的獨(dú)立封裝等方面都可以看出來,它主要負(fù)責(zé)與用戶進(jìn)行交互。
Service則是在后臺運(yùn)行,默默地為用戶提供功能,進(jìn)行調(diào)度和統(tǒng)籌。如果一棵樹的地上部分是Activity的話,它龐大的根須就是Service。Android的服務(wù)組件沒有運(yùn)行在獨(dú)立的進(jìn)程或線程中,它和其他的組件一樣也在應(yīng)用的主線程中運(yùn)行,如果服務(wù)組件執(zhí)行比較耗時的操作就會導(dǎo)致主線程阻塞或者假死,從而無法響應(yīng)用戶的操作。
因此,耗時的操作不要放在UI線程中,因為UI 5S,廣播10s就阻塞了,會引發(fā)ANR。
②從使用的角度來講:
Service不僅可以給Activity建立雙向連接,為Activity提供數(shù)據(jù)和功能支持,也可以單向接受Intent的請求,進(jìn)行數(shù)據(jù)的分析處理和功能調(diào)度。
③從扮演的角色來講:
Activity的功能比較單一,主要就是顯示應(yīng)用所具有的一些功能,幫助用戶與應(yīng)用進(jìn)行交互,像一個人的臉。而Service可能扮演功能調(diào)度者也能扮演功能提供者,從觸發(fā)器收集信息進(jìn)行分析和處理,然后更新界面,修改數(shù)據(jù)或進(jìn)行其他操作時是一個功能調(diào)度者,從輸入法的選擇考慮Service扮演的就是一個功能提供者。View組件是Android中用戶能夠?qū)崒嵲谠诳吹降牟糠?,如按鈕,輸入框等就是繼承自這個類,View只有裝入Activity這樣的容器中才有意義,而反過來Activity裝入了這些View后才能夠成功完成與用戶交互的任務(wù),但是Service不需要這些花哨的東西,只需要默默地等待事件發(fā)生或者聽候差遣。
Android啟動Service有兩種方法,一種是startService,一種是bindService。生命周期如下:

執(zhí)行startService時,調(diào)用者如果沒有stopService,Service會一直在后臺運(yùn)行。多次調(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)建服務(wù)和綁定服務(wù)。 多個組件可以同時綁定到該服務(wù),但全部取消綁定后,該服務(wù)即會被銷毀。
既使用startService又使用bindService的情況,需要unbindService和stopService同時調(diào)用才會終止Service。
Activity與Service交互有兩種方法:一種是使用broadcast,另一種是使用bindService。本文只介紹bindService方法。
public class MsgService extends Service {
public MsgService() {
}
/**
* 進(jìn)度條的最大值
*/
public static final int MAX_PROGRESS = 100;
/**
* 進(jìn)度條的進(jìn)度值
*/
private int progress = 0;
/**
* 增加get()方法,供Activity調(diào)用
*
* @return 下載進(jìn)度
*/
public int getProgress() {
return progress;
}
/**
* 模擬下載任務(wù),每秒鐘更新一次
*/
public void startDownLoad(){
new Thread(new Runnable() {
@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;
//進(jìn)度發(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);
}
/**
* 更新進(jìn)度的回調(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模擬耗時的下載任務(wù),MainActivity 綁定服務(wù),通過注冊O(shè)nProgressListener回調(diào)獲取下載進(jìn)度,更新進(jìn)度條。
本例子Activity和Service是在同一個進(jìn)程中,對于跨進(jìn)程調(diào)用Service需要使用到AIDL技術(shù)。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Android檢測Activity或者Service是否運(yùn)行的方法
- Android中Service和Activity相互通信示例代碼
- Android中Service與Activity之間通信的幾種方式
- Android Activity與Service通信(不同進(jìn)程之間)詳解
- 淺談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)文章
item高度不同時Recyclerview獲取滑動距離的方法
這篇文章主要介紹了item高度不同時Recyclerview獲取滑動距離的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11
Android使用View Animation實現(xiàn)動畫加載界面
這篇文章主要為大家詳細(xì)介紹了Android使用View Animation實現(xiàn)動畫加載界面的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置)
本篇文章主要介紹了android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置),具有一定的參考價值,有興趣的可以了解一下2017-09-09
2013年 移動App設(shè)計13項注意細(xì)節(jié)總結(jié)
在過去的一年里,移動成主流也讓眾多的移動應(yīng)用如雨后春筍般層出不窮,在眾多開發(fā)者從中獲利的同時競爭也愈演愈烈,如何才能保證自己立于不敗之地接下來介紹移動App設(shè)計的13大精髓感興趣的朋友可以了解下啊2013-01-01
Android中利用NetworkInfo判斷網(wǎng)絡(luò)狀態(tài)時出現(xiàn)空指針(NullPointerException)問題的解決
這篇文章主要介紹了Android中利用NetworkInfo判斷網(wǎng)絡(luò)狀態(tài)時出現(xiàn)空指針(NullPointerException)問題的解決方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-11-11
Android點擊事件之多點觸摸與手勢識別的實現(xiàn)
這篇文章主要介紹了Android點擊事件之多點觸摸與手勢識別的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
Android判斷軟鍵盤的狀態(tài)和隱藏軟鍵盤的簡單實例
下面小編就為大家?guī)硪黄狝ndroid判斷軟鍵盤的狀態(tài)和隱藏軟鍵盤的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10

