Android安卓进程保活(二)
生活随笔
收集整理的這篇文章主要介紹了
Android安卓进程保活(二)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Android進(jìn)程保活·設(shè)置前臺Service,提升App進(jìn)程優(yōu)先級
Android進(jìn)程
此文章代碼Github上有提交:https://github.com/NorthernBrain/processKeep_Service/tree/master
首先你要知道Android中的進(jìn)程以及它的優(yōu)先級,下面來說明它進(jìn)程
下面進(jìn)行解釋:
前臺進(jìn)程(Foreground process):
用戶當(dāng)前操作所必需的進(jìn)程。如果一個(gè)進(jìn)程滿足以下任一條件,即視為前臺進(jìn)程:- 托管用戶正在交互的 Activity(已調(diào)用 Activity 的 onResume() 方法)
- 托管某個(gè) Service,后者綁定到用戶正在交互的 Activity
- 托管正在“前臺”運(yùn)行的 Service(服務(wù)已調(diào)用 startForeground())
- 托管正執(zhí)行一個(gè)生命周期回調(diào)的 Service(onCreate()、onStart() 或 onDestroy())
- 托管正執(zhí)行其 onReceive() 方法的 BroadcastReceiver
可見進(jìn)程 (Visible process):
沒有任何前臺組件、但仍會影響用戶在屏幕上所見內(nèi)容的進(jìn)程。 如果一個(gè)進(jìn)程滿足以下任一條件,即視為可見進(jìn)程:- 托管不在前臺、但仍對用戶可見的 Activity(已調(diào)用其 onPause() 方法)。例如,如果前臺 Activity 啟動了一個(gè)對話框,允許在其后顯示上一 Activity,則有可能會發(fā)生這種情況。
- 托管綁定到可見(或前臺)Activity 的 Service。
可見進(jìn)程被視為是極其重要的進(jìn)程,除非為了維持所有前臺進(jìn)程同時(shí)運(yùn)行而必須終止,否則系統(tǒng)不會終止這些進(jìn)程。
服務(wù)進(jìn)程 (Service process):
正在運(yùn)行已使用 startService() 方法啟動的服務(wù)且不屬于上述兩個(gè)更高類別進(jìn)程的進(jìn)程。盡管服務(wù)進(jìn)程與用戶所見內(nèi)容沒有直接關(guān)聯(lián),但是它們通常在執(zhí)行一些用戶關(guān)心的操作(例如,在后臺播放音樂或從網(wǎng)絡(luò)下載數(shù)據(jù))。因此,除非內(nèi)存不足以維持所有前臺進(jìn)程和可見進(jìn)程同時(shí)運(yùn)行,否則系統(tǒng)會讓服務(wù)進(jìn)程保持運(yùn)行狀態(tài)。后臺進(jìn)程 (Service process):
包含目前對用戶不可見的 Activity 的進(jìn)程(已調(diào)用 Activity 的 onStop() 方法)。這些進(jìn)程對用戶體驗(yàn)沒有直接影響,系統(tǒng)可能隨時(shí)終止它們,以回收內(nèi)存供前臺進(jìn)程、可見進(jìn)程或服務(wù)進(jìn)程使用。 通常會有很多后臺進(jìn)程在運(yùn)行,因此它們會保存在 LRU (最近最少使用)列表中,以確保包含用戶最近查看的 Activity 的進(jìn)程最后一個(gè)被終止。如果某個(gè) Activity 正確實(shí)現(xiàn)了生命周期方法,并保存了其當(dāng)前狀態(tài),則終止其進(jìn)程不會對用戶體驗(yàn)產(chǎn)生明顯影響,因?yàn)楫?dāng)用戶導(dǎo)航回該 Activity 時(shí),Activity 會恢復(fù)其所有可見狀態(tài)。空進(jìn)程 (Empty process):
不含任何活動應(yīng)用組件的進(jìn)程。保留這種進(jìn)程的的唯一目的是用作緩存,以縮短下次在其中運(yùn)行組件所需的啟動時(shí)間。 為使總體系統(tǒng)資源在進(jìn)程緩存和底層內(nèi)核緩存之間保持平衡,系統(tǒng)往往會終止這些進(jìn)程。進(jìn)程優(yōu)先級:
首先空進(jìn)程是最先被回收的,其次便是后臺進(jìn)程,依次往上,前臺進(jìn)程是最后才會被結(jié)束。Android進(jìn)程保活
有很多種方法可以實(shí)現(xiàn)Android的進(jìn)程保活,比如通過?1像素且透明Activity提升App進(jìn)程優(yōu)先級、通過設(shè)置前臺Service提升App進(jìn)程優(yōu)先級、Java層的雙進(jìn)程拉活、JobScheduler實(shí)現(xiàn)、NDK雙進(jìn)程守護(hù)、使用賬戶同步拉活、workmanager實(shí)現(xiàn)。下面這幅圖,說明的是:
- 紅色部分是容易被回收的進(jìn)程,屬于android進(jìn)程
- 綠色部分是較難被回收的進(jìn)程,屬于android進(jìn)程
- 其他部分則不是android進(jìn)程,也不會被系統(tǒng)回收,一般是ROM自帶的app和服務(wù)才能擁有
本篇文章介紹的是進(jìn)程第二種方式:
- 設(shè)置前臺Service,提升App進(jìn)程優(yōu)先級
設(shè)置前臺Service,提升App進(jìn)程優(yōu)先級:
首先創(chuàng)建ForegroundService.java繼承自Service(android.app.Service):↓
這里要注意,不同的Android版本,所用的方式也就不同,并且不能顯示通知欄,這里需要在onStartCommand中判斷Android版本,選擇不同的操作
public class ForegroundService extends Service {private static final int SERVICE_ID = 1;public void onCreate() {super.onCreate();Log.d("ForegroundServiceNew", "開啟ForegroundService");}public void onDestroy() {super.onDestroy();Log.d("ForegroundServiceNew", "銷毀ForegroundService");}public IBinder onBind(Intent intent) {return null;}(api = Build.VERSION_CODES.O)public int onStartCommand(Intent intent, int flags, int startId) {//判斷版本if (Build.VERSION.SDK_INT < 18) {//Android4.3以下版本//將Service設(shè)置為前臺服務(wù),可以取消通知欄消息startForeground(SERVICE_ID, new Notification());} else if (Build.VERSION.SDK_INT < 24) {//Android4.3 - 7.0之間//將Service設(shè)置為前臺服務(wù),可以取消通知欄消息startForeground(SERVICE_ID, new Notification());startService(new Intent(this, InnerService.class));} else {//Android 8.0以上NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);if (manager != null) {NotificationChannel channel = new NotificationChannel("channel","name",NotificationManager.IMPORTANCE_NONE);manager.createNotificationChannel(channel);NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"channel");//將Service設(shè)置為前臺服務(wù),Android 8.0 App啟動不會彈出通知欄消息,退出后臺會彈出通知消息//Android9.0啟動時(shí)候會立刻彈出通知欄消息startForeground(SERVICE_ID,new Notification());}}return START_STICKY;}public static class InnerService extends Service {public IBinder onBind(Intent intent) {return null;}public int onStartCommand(Intent intent, int flags, int startId) {startForeground(SERVICE_ID, new Notification());stopForeground(true);//移除通知欄消息stopSelf();return super.onStartCommand(intent, flags, startId);}}}復(fù)制代碼加入權(quán)限 <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> 復(fù)制代碼
最后在MainActivity啟動服務(wù)就行:↓ public class MainActivity extends AppCompatActivity {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//設(shè)置前臺Service,提升App進(jìn)程優(yōu)先級startService(new Intent(this,ForegroundService.class));} }復(fù)制代碼
轉(zhuǎn)載于:https://juejin.im/post/5c1b8a9b6fb9a049e70212b8
總結(jié)
以上是生活随笔為你收集整理的Android安卓进程保活(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作为Java工程师,你的Spring用对
- 下一篇: 直接拿来用!最火的Android开源项目