Android入門之Service的使用詳解
簡(jiǎn)介
我們的Android在啟動(dòng)一些長(zhǎng)事務(wù)時(shí)都會(huì)使用異步,很多初學(xué)者覺得這個(gè)異步就是一個(gè)異步線程+Handler而己。如果你這么想就錯(cuò)了。這一切其實(shí)靠的正是Android里的Service。
Service分成普通Service和IntentService兩種。而啟動(dòng)又發(fā)為兩對(duì):
- 第一對(duì),startService/stopService;
- 第二對(duì),bindService/unbindService;
后面開始我們就逐步展開對(duì)Android Service的講述,我盡量也以“保姆式教程”的方法來引領(lǐng)著大家循序漸進(jìn)的入門,以求牢固掌握這些基礎(chǔ)的東西。
下面我們就來講Android中最最簡(jiǎn)單的Service使用。
什么是Service
Service和Thread的區(qū)別。其實(shí)他們兩者并沒有太大的關(guān)系,不過有很多朋友經(jīng)常把這兩個(gè)混淆了! Thread是線程,程序執(zhí)行的最小單元,分配CPU的基本單位! 而Service則是Android提供一個(gè)允許長(zhǎng)時(shí)間留駐后臺(tái)的一個(gè)組件,最常見的 用法就是做輪詢操作!或者想在后臺(tái)做一些事情,比如后臺(tái)下載更新! 記得別把這兩個(gè)概念混淆。
所以通過上面的理論我們知道,service有兩種啟動(dòng)方式:
- startService/stopService
- bindService/unBindservice
我們就說startService,這個(gè)start一下去,整個(gè)service的生命周期就變得非常非常有用了。
為什么這么說呢?
因?yàn)槟阋獙懸粋€(gè)service時(shí),經(jīng)常會(huì)遇到:何時(shí)給它賦初始值?何時(shí)處理?何時(shí)回調(diào)?何時(shí)結(jié)束?
這就是“生命周期”的重要性。
各位不要感到“枯燥”,就像spring boot的生命周期,當(dāng)你的業(yè)務(wù)場(chǎng)景足夠復(fù)雜時(shí),這種生命周期中大部分點(diǎn)你是需要Override到的。如果有些朋友你覺得生命周期從來沒什么用那說明你所在的項(xiàng)目已經(jīng)足夠簡(jiǎn)單到?jīng)]什么工作經(jīng)驗(yàn)、技術(shù)含量可言了,那么我奉勸你如果長(zhǎng)時(shí)間在這么沒有含量的項(xiàng)目?jī)?nèi)你要考慮自身是不是會(huì)栽在35、40這個(gè)梗上了,這是很危險(xiǎn)的一個(gè)信號(hào)。
Service的生命周期
本著保姆式教程的精神,我們說經(jīng)常會(huì)使用到的Service的生命周期。各位記得,startService和bindService的啟動(dòng)決定著它的生命周期也不相同。
startService和bindService的區(qū)別
服務(wù)不能自己運(yùn)行。一旦Activity中調(diào)用了startService()方法啟動(dòng)Service后,Activity就不能直接控制Service了。這時(shí)就需要bindService()把Activity和Service聯(lián)系起來,之后就能在Activity中指揮Service去工作了。
startService()和bindService()都能啟動(dòng)Service,它們的調(diào)用順序也會(huì)對(duì)Service產(chǎn)生影響,具體影響我們看下去。
startService ()時(shí)Service的生命周期
通過startService(),Service會(huì)經(jīng)歷 onCreate() –> onStart() 啟動(dòng)Service。然后stopService()的時(shí)候直接onDestroy()。如果調(diào)用者直接退出而沒有調(diào)用stopService(),那么Service會(huì)一直在后臺(tái)運(yùn)行。 注意在Service的一個(gè)生命周期之內(nèi)只會(huì)調(diào)用一次onCreate()方法,stopService()之前若多次startService()則只會(huì)調(diào)用onStart()方法。
bindService()時(shí)Service的生命周期
如果打算采用bindService()方法啟動(dòng)服務(wù),在服務(wù)未被創(chuàng)建時(shí),系統(tǒng)會(huì)先調(diào)用服務(wù)的onCreate()方法,接著調(diào)用onBind()方法。這個(gè)時(shí)候調(diào)用者和服務(wù)綁定在一起,調(diào)用者unbindService()退出了,系統(tǒng)就會(huì)先調(diào)用服務(wù)的onUnbind()方法,接著調(diào)用onDestroy()方法。多次調(diào)用bindService()方法并不會(huì)導(dǎo)致多次創(chuàng)建服務(wù)及綁定(也就是說onCreate()和onBind()方法并不會(huì)被多次調(diào)用)。
如果bindService()之前Service已經(jīng)在運(yùn)行了,那么這是調(diào)用unbindService()只會(huì)onUnbind()而不會(huì)onDestory()。
以一個(gè)例子我們先來看start/stop一個(gè)service以下它的生命周期是如何經(jīng)歷的。
例子
我們的界面上就兩個(gè)按鈕,一個(gè)startService,一個(gè)stopService。
來看具體的代碼
全代碼
后端代碼
service類-SimpleService類
package org.mk.android.demoandroidsimpleservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class SimpleService extends Service { private final String TAG = "SimpleService"; public SimpleService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. Log.i(TAG, ">>>>>>onBind方法被調(diào)用"); return null; } //Service被創(chuàng)建時(shí)調(diào)用 @Override public void onCreate() { Log.i(TAG, ">>>>>>onCreate方法被調(diào)用"); super.onCreate(); } //Service被啟動(dòng)時(shí)調(diào)用 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, ">>>>>>onStartCommand方法被調(diào)用"); return super.onStartCommand(intent, flags, startId); } //Service被關(guān)閉之前回調(diào) @Override public void onDestroy() { Log.i(TAG, ">>>>>>onDestory方法被調(diào)用"); super.onDestroy(); } }
運(yùn)行主類
package org.mk.android.demoandroidsimpleservice; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button buttonStartSimpleService; private Button buttonStopSimpleService; private Intent intent = new Intent(); private Context ctx; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ctx = MainActivity.this; buttonStartSimpleService = (Button) findViewById(R.id.buttonStartSimpleService); buttonStopSimpleService = (Button) findViewById(R.id.buttonStopSimpleService); buttonStartSimpleService.setOnClickListener(new OnClickListener()); buttonStopSimpleService.setOnClickListener(new OnClickListener()); } class OnClickListener implements View.OnClickListener { @Override public void onClick(View view) { Intent eIntent; switch (view.getId()) { case R.id.buttonStartSimpleService: intent=new Intent(ctx,SimpleService.class); startService(intent); break; case R.id.buttonStopSimpleService: intent=new Intent(ctx,SimpleService.class); stopService(intent); break; } } } }
為了運(yùn)行Service你還需要在AndroidManifest.xml文件中注冊(cè)這個(gè)Service
注意下文中的<service>塊。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DemoAndroidSimpleService" tools:targetApi="31"> <service android:name=".SimpleService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="org.mk.android.demoandroidsimpleservice.SimpleService"/> </intent-filter> </service> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="" /> </activity> </application> </manifest>
運(yùn)行后的效果
這個(gè)運(yùn)行后的效果恰恰說明了一個(gè)這樣的效果:通過startService啟動(dòng)的Service的生命周期不會(huì)觸碰到那些bindService才擁有的生命周期中。
到此這篇關(guān)于Android入門之Service的使用詳解的文章就介紹到這了,更多相關(guān)Android Service內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android?NotificationListenerService通知監(jiān)聽服務(wù)使用
- Android Google AutoService框架使用詳解
- Android使用Service實(shí)現(xiàn)IPC通信的2種方式
- 說說在Android如何使用服務(wù)(Service)的方法
- Android使用Service實(shí)現(xiàn)簡(jiǎn)單音樂播放實(shí)例
- 淺談Android中Service的注冊(cè)方式及使用
- Android編程使用Service實(shí)現(xiàn)Notification定時(shí)發(fā)送功能示例
- Android 通知使用權(quán)(NotificationListenerService)的使用
- Android Service功能使用示例代碼
相關(guān)文章
Android利用Palette實(shí)現(xiàn)提取圖片顏色
Palette是一個(gè)類似調(diào)色板的工具類,根據(jù)傳入的bitmap,提取出主體顏色,使得圖片和顏色更加搭配,界面更協(xié)調(diào)。本文將詳解如何利用Palette實(shí)現(xiàn)提取圖片顏色,需要的可以參考一下2022-03-03詳解Android如何設(shè)計(jì)一個(gè)全局可調(diào)用的ViewModel對(duì)象
很多時(shí)候我們需要維護(hù)一個(gè)全局可用的ViewModel,因?yàn)檫@樣可以維護(hù)全局同一份數(shù)據(jù)源,且方便使用協(xié)程綁定App的生命周期,那如何設(shè)計(jì)全局可用的ViewModel對(duì)象,文中介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05Android6.0 storage目錄sd卡存儲(chǔ)的路徑創(chuàng)建詳解
這篇文章主要介紹了Android6.0 storage目錄sd卡存儲(chǔ)的路徑創(chuàng)建的相關(guān)資料,需要的朋友可以參考下2017-01-01Android仿QQ個(gè)人標(biāo)簽添加與刪除功能
這篇文章主要為大家詳細(xì)介紹了Android仿QQ個(gè)人標(biāo)簽添加與刪除功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Android實(shí)現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動(dòng)態(tài)更新的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動(dòng)態(tài)更新的方法,結(jié)合實(shí)例形式詳細(xì)分析了ListView異步加載數(shù)據(jù)的操作步驟與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-08-08Android實(shí)現(xiàn)測(cè)試環(huán)境噪音分貝
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)測(cè)試環(huán)境噪音分貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01解析Android應(yīng)用啟動(dòng)后自動(dòng)創(chuàng)建桌面快捷方式的實(shí)現(xiàn)方法
和IOS開發(fā)和Windows Phone開發(fā)相比,Android是開放的,Android上的開發(fā)也相對(duì)更加靈活,能夠做很多事情。有的朋友會(huì)發(fā)現(xiàn),在某些Android應(yīng)用安裝以后,第一次運(yùn)行,就會(huì)在桌面創(chuàng)建快捷方式。這是如何做到的呢2013-05-05Android Toast的幾種使用方式及注意事項(xiàng)
Toast是Android中常用的組件,下面介紹下Toast使用的幾種方式和注意事項(xiàng),本文給大家分享Toast的使用方式,感興趣的朋友一起看看吧2024-02-02