摘要:只能執(zhí)行單一操作,無(wú)法返回結(jié)果給調(diào)用方,常用于網(wǎng)絡(luò)下載上傳文件,播放音樂等。綁定模式此模式通過綁定組件等調(diào)用啟動(dòng)此服務(wù)隨綁定組件的消亡而解除綁定。
極力推薦文章:歡迎收藏
Android 干貨分享
本篇文章主要介紹 Android 開發(fā)中的部分知識(shí)點(diǎn),通過閱讀本篇文章,您將收獲以下內(nèi)容:
Service 簡(jiǎn)介
四大組件之一,必須在Androidmainfest.xml 中注冊(cè)
啟動(dòng)模式啟動(dòng)服務(wù)
綁定模式綁定服務(wù)
前臺(tái)服務(wù)
AIDL遠(yuǎn)程服務(wù)
Service 是 Android 四大組件之一(Activity 活動(dòng),Service 服務(wù),ContentProvider 內(nèi)容提供者,BroadcastReceiver 廣播),與Activity相比,Activity 是運(yùn)行在前臺(tái),用戶可以看得見,Service 則是運(yùn)行在后臺(tái),無(wú)用戶界面,用戶無(wú)法看到。
Service主要用于組件之間交互(例如:與Activity、ContentProvider、BroadcastReceiver進(jìn)行交互)、后臺(tái)執(zhí)行耗時(shí)操作等(例如下載文件,播放音樂等,但Service在主線程運(yùn)行時(shí)長(zhǎng)不能超過20s,否則會(huì)出現(xiàn)ANR,耗時(shí)操作一般建議在子線程中進(jìn)行操作)。
1.Service 簡(jiǎn)介在了解Service 的生命周期的之前,我們先了解一下Service 的繼承關(guān)系,方便我們更好的了解Service。
Service 繼承關(guān)系如下:java.lang.Object ? android.content.Context ? android.content.ContextWrapper ? android.app.ServiceService 的兩種啟動(dòng)模式
Service 有兩種不同的啟動(dòng)模式 ,不同的啟動(dòng)模式對(duì)應(yīng)不同生命周期.
Service 啟動(dòng)模式主要分兩種: 1. 啟動(dòng)模式。 2. 綁定模式。
此模式通過 startService()方法啟動(dòng),此服務(wù)可以在后臺(tái)一直運(yùn)行,不會(huì)隨啟動(dòng)組件的消亡而消亡。只能執(zhí)行單一操作,無(wú)法返回結(jié)果給調(diào)用方,常用于網(wǎng)絡(luò)下載、上傳文件,播放音樂等。
2.綁定模式此模式 通過綁定組件(Activity等)調(diào)用 bindService() 啟動(dòng),此服務(wù)隨綁定組件的消亡而解除綁定。
如果此時(shí)沒有其它通過startService()啟動(dòng),則此服務(wù)會(huì)隨綁定組件的消亡而消亡。
多個(gè)組件不僅可以同時(shí)綁定一個(gè)Service,而且可以通過進(jìn)程間通信(IPC)執(zhí)行跨進(jìn)程操作等。
啟動(dòng)模式與綁定模式的服務(wù)可以同時(shí)運(yùn)行,在銷毀服務(wù)時(shí),只有兩種模式都不在使用Service時(shí)候,才可以銷毀服務(wù),否則會(huì)引起異常。
4. 兩種 Service 模式的生命周期兩種 Service 模式的生命周期如下:
2.四大組件之一,必須在Androidmainfest.xml 中注冊(cè) Service 注冊(cè)方法如下:注意:... ...
Service 如不注冊(cè) ,不會(huì)像Activity 那樣會(huì)導(dǎo)致App Crash,Service 不注冊(cè) 不會(huì)報(bào)異常信息,但是服務(wù)會(huì)起不來(lái),如不注意很容易迷惑。
3.啟動(dòng)模式通過啟動(dòng)模式啟動(dòng)的Service ,如不主動(dòng)關(guān)閉,Service會(huì)一直在。
啟動(dòng)模式啟動(dòng)服務(wù)的方法Intent mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class); startService(mStartIntent);啟動(dòng)模式啟動(dòng)服務(wù)的生命周期
下面是驗(yàn)證啟動(dòng)模式啟動(dòng)服務(wù)的生命周期的方法,詳細(xì)生命周期請(qǐng)查看上方Service的生命周期圖。
01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService?wjwj:: ----onCreate---- 01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService?wjwj:: ----onStartCommand---- 01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService?wjwj:: ----onDestroy----啟動(dòng)模式 啟動(dòng)服務(wù)案例
此案例功能:?jiǎn)?dòng)服務(wù),在服務(wù)中創(chuàng)建通知
// Service 創(chuàng)建方法 @Override public void onCreate() { super.onCreate(); Log.i(TAG, "----onCreate----"); } // Service 啟動(dòng)方法 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "----onStartCommand----"); // 獲取NotificationManager實(shí)例 notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // 實(shí)例化NotificationCompat.Builder并設(shè)置相關(guān)屬性 NotificationCompat.Builder builder = new NotificationCompat.Builder( this) // 設(shè)置小圖標(biāo) .setSmallIcon(R.drawable.ic_launcher) .setLargeIcon( BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)) // 設(shè)置通知標(biāo)題 .setContentTitle("我是通過StartService服務(wù)啟動(dòng)的通知") // 設(shè)置通知不能自動(dòng)取消 .setAutoCancel(false).setOngoing(true) // 設(shè)置通知時(shí)間,默認(rèn)為系統(tǒng)發(fā)出通知的時(shí)間,通常不用設(shè)置 // .setWhen(System.currentTimeMillis()) // 設(shè)置通知內(nèi)容 .setContentText("請(qǐng)使用StopService 方法停止服務(wù)"); // 通過builder.build()方法生成Notification對(duì)象,并發(fā)送通知,id=1 notifyManager.notify(1, builder.build()); return super.onStartCommand(intent, flags, startId); } // Service 銷毀方法 @Override public void onDestroy() { Log.i(TAG, "----onDestroy----"); notifyManager.cancelAll(); super.onDestroy(); }4. 綁定模式啟動(dòng)綁定服務(wù)
綁定模式啟動(dòng)的服務(wù)會(huì)隨著綁定逐漸的消亡而解除Service綁定,如果此時(shí)Service沒有通過啟動(dòng)模式啟動(dòng),則此服務(wù)將會(huì)被銷毀。
綁定模式啟動(dòng)綁定服務(wù)的方法綁定模式,是通過其他組件啟動(dòng)的Service。
啟動(dòng)綁定模式服務(wù)的方法// 啟動(dòng)綁定服務(wù)處理方法 public void BtnStartBindService(View view) { // 啟動(dòng)綁定服務(wù)處理方法 bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE); isBindService = true; Toast.makeText(ServiceMethod.this, "啟動(dòng) " + mBindCount + " 次綁定服務(wù)", Toast.LENGTH_SHORT).show(); } public void BtnSopBindService(View view) { if (isBindService) { // 解除綁定服務(wù)處理方法 unbindService(serviceConnection); Toast.makeText(ServiceMethod.this, "解除 " + mUnBindCount + " 次綁定服務(wù)", Toast.LENGTH_SHORT).show(); isBindService = false; } }
綁定服務(wù) 隨綁定組件的消亡而消亡
綁定模式 生命周期回調(diào)代碼如下:// Service 創(chuàng)建方法 @Override public void onCreate() { super.onCreate(); Log.i(TAG, "----onCreate----"); } // Service 綁定方法 @Override public IBinder onBind(Intent intent) { Log.i(TAG, "----onBind----"); MyBinder myBinder = new MyBinder(); return myBinder; } // Service 解除綁定方法 @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "----onUnbind----"); return super.onUnbind(intent); } // Service 銷毀方法 @Override public void onDestroy() { Log.i(TAG, "----onDestroy----"); super.onDestroy(); }
綁定服務(wù)的生命周期代碼打印Log信息如下:
01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService?wjwj:: ----onCreate---- 01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService?wjwj:: -----onBind----- 01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService?wjwj:: ----onUnbind---- 01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService?wjwj:: ----onDestroy----綁定服務(wù)案例
功能:獲取綁定模式啟動(dòng) 綁定服務(wù)及解除綁定服務(wù)的次數(shù)
綁定服務(wù)類package com.android.program.programandroid.component.Service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class BindServiceMethods extends Service { private static final String TAG = "BindService wjwj:"; public BindServiceMethods() { } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "----onCreate----"); } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "----onBind----"); MyBinder myBinder = new MyBinder(); return myBinder; } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "----onUnbind----"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.i(TAG, "----onDestroy----"); super.onDestroy(); } }
組件與綁定服務(wù)類之間的交互
// 啟動(dòng)綁定服務(wù)處理方法 public void BtnStartBindService(View view) { bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE); isBindService = true; Toast.makeText(ServiceMethods.this,"啟動(dòng) "+mBindCount+" 次綁定服務(wù)",Toast.LENGTH_SHORT).show(); } // 解除綁定服務(wù)處理方法 public void BtnSopBindService(View view) { if (isBindService) { unbindService(serviceConnection); Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次綁定服務(wù)",Toast.LENGTH_SHORT).show(); isBindService=false; } }
組件之間交互所需的 Binder 接口類
/** * 該類提供 綁定組件與綁定服務(wù)提供接口 * */ public class MyBinder extends Binder { private int count = 0; public int getBindCount() { return ++count; } public int getUnBindCount() { return count> 0 ? count-- : 0; } }5. 提高服務(wù)的優(yōu)先級(jí)
服務(wù)默認(rèn)啟動(dòng)方式是后臺(tái)服務(wù),但是可以通過設(shè)置服務(wù)為前臺(tái)服務(wù),提高服務(wù)的優(yōu)先級(jí),進(jìn)而避免手機(jī)內(nèi)存緊張時(shí),服務(wù)進(jìn)程被殺掉。
設(shè)置前臺(tái)服務(wù)的兩種方法1.設(shè)置為前臺(tái)服務(wù)
//設(shè)置為前臺(tái)服務(wù) startForeground(int, Notification)
2.取消前臺(tái)服務(wù)
//取消為前臺(tái)服務(wù) stopForeground(true);startForeground 前臺(tái)服務(wù)案例
功能:前臺(tái)服務(wù)綁定通知信息,提高服務(wù)進(jìn)程優(yōu)先級(jí),否則取消通知信息
package com.android.program.programandroid.component.Service; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; import android.graphics.BitmapFactory; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import com.android.program.programandroid.R; public class MyStartForcegroundService extends Service { public MyStartForcegroundService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction().equals("start_forceground_service")) { // 獲取NotificationManager實(shí)例 NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // 實(shí)例化NotificationCompat.Builder并設(shè)置相關(guān)屬性 NotificationCompat.Builder builder = new NotificationCompat.Builder(this) // 設(shè)置小圖標(biāo) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) // 設(shè)置通知標(biāo)題 .setContentTitle("我是通過startForeground 啟動(dòng)前臺(tái)服務(wù)通知") // 設(shè)置通知不能自動(dòng)取消 .setAutoCancel(false) .setOngoing(true) // 設(shè)置通知時(shí)間,默認(rèn)為系統(tǒng)發(fā)出通知的時(shí)間,通常不用設(shè)置 // .setWhen(System.currentTimeMillis()) // 設(shè)置通知內(nèi)容 .setContentText("請(qǐng)使用stopForeground 方法改為后臺(tái)服務(wù)"); //通過builder.build()方法生成Notification對(duì)象,并發(fā)送通知,id=1 // 設(shè)置為前臺(tái)服務(wù) startForeground(1, builder.build()); } else if (intent.getAction().equals("stop_forceground_service")) { stopForeground(true); } return super.onStartCommand(intent, flags, startId); } }6. 使用AIDL接口實(shí)現(xiàn)遠(yuǎn)程綁定
由于內(nèi)容較多,后續(xù)另開一篇詳細(xì)介紹。
至此,本篇已結(jié)束,如有不對(duì)的地方,歡迎您的建議與指正。同時(shí)期待您的關(guān)注,感謝您的閱讀,謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75818.html
摘要:二簡(jiǎn)要介紹是一段腳本,在后臺(tái)運(yùn)行。作為一個(gè)獨(dú)立的線程,不會(huì)對(duì)頁(yè)面造成阻塞。本質(zhì)上充當(dāng)應(yīng)用程序與瀏覽器之間的代理服務(wù)器??梢宰龅诫x線使用消息推送后臺(tái)自動(dòng)更新,的出現(xiàn)是正是為了使得也可以具有類似的能力。在我們的例子例,是在,的根目錄是。 一、背景 taro框架轉(zhuǎn)的h5,想在無(wú)網(wǎng)絡(luò)狀態(tài)下可以控制展示給用戶的界面,使用客戶端離線緩存可以達(dá)到目的,并且可以將靜態(tài)資源進(jìn)行緩存,從而減少白屏?xí)r間,加...
摘要:了解的相關(guān)術(shù)語(yǔ)通知通知定義了切面是什么,以及何時(shí)使用。描述了切面要完成的工作和何時(shí)需要執(zhí)行這個(gè)工作。就是用來(lái)配置切面設(shè)置代理模式。 了解AOP的相關(guān)術(shù)語(yǔ) 1.通知(Advice): 通知定義了切面是什么,以及何時(shí)使用。描述了切面要完成的工作和何時(shí)需要執(zhí)行這個(gè)工作。 2.連接點(diǎn)(Joinpoint): 程序能夠應(yīng)用通知的一個(gè)時(shí)機(jī),這些時(shí)機(jī)就是連接點(diǎn),例如方法被調(diào)用時(shí)、異常被拋出時(shí)等等。 ...
摘要:樣例啟動(dòng)服務(wù)啟動(dòng)服務(wù)文件說(shuō)明參數(shù)說(shuō)明服務(wù)的說(shuō)明描述服務(wù)描述服務(wù)類別服務(wù)運(yùn)行參數(shù)的設(shè)置是后臺(tái)運(yùn)行的形式為服務(wù)的具體運(yùn)行命令為重啟命令為停止命令表示給服務(wù)分配獨(dú)立的臨時(shí)空間服務(wù)安裝的相關(guān)設(shè)置,可設(shè)置為多用戶注意啟動(dòng)重啟停止命樣例:?jiǎn)?dòng) Seahub 服務(wù)[Unit] Description=Seafile Seahub After=network.target seafile.service...
閱讀 2376·2023-04-25 20:07
閱讀 3312·2021-11-25 09:43
閱讀 3671·2021-11-16 11:44
閱讀 2538·2021-11-08 13:14
閱讀 3186·2021-10-19 11:46
閱讀 903·2021-09-28 09:36
閱讀 2998·2021-09-22 10:56
閱讀 2382·2021-09-10 10:51