Service詳解及應(yīng)用(一)-- 進(jìn)程詳解篇

使用手機(jī)的時(shí)候,你明明已經(jīng)把這個(gè)APP關(guān)掉了,怎么過一會兒它自己又啟動(dòng)了,什么歌情況。特別是某些全家桶,經(jīng)常是這種情況,你壓根殺不掉。還有之前網(wǎng)上有報(bào)道某些APP會監(jiān)聽用戶打電話,偷偷錄音并上傳,這些是怎么做到的。使用某些下載軟件的時(shí)候,軟件已經(jīng)關(guān)閉,但是下載卻沒停止。
對于以上行為,我表示非常不贊同,所以這篇文章會告訴你上面的是怎么做到的,O(∩_∩)O哈哈~

進(jìn)程優(yōu)先級

不是說講解Service么?怎么講這個(gè)了?別急,慢慢來。開篇說了某些應(yīng)用會自啟動(dòng),無法殺死,而有的應(yīng)用退到后臺,某一段時(shí)間再次打開時(shí),它重啟了。說明這是被系統(tǒng)殺死的。要知道,在Android中,一般情況下一個(gè)APP的所有組件(四大組件)都是是運(yùn)行在一個(gè)進(jìn)程中的,所以系統(tǒng)殺死的就是這個(gè)進(jìn)程,進(jìn)程被干掉了,APP也就沒了。系統(tǒng)殺死進(jìn)程的原因是因?yàn)橄到y(tǒng)的內(nèi)存資源比較緊張,系統(tǒng)需要為一些急需內(nèi)存資源的組件去提供足夠的內(nèi)存資源,所以系統(tǒng)就把一些進(jìn)程殺死了。

這里說的一般情況下一個(gè)APP的所有組件都是是運(yùn)行在一個(gè)進(jìn)程中的言外之意指的是,你可以指定某些組件運(yùn)行在指定的進(jìn)程中的??梢栽谇鍐挝募羞M(jìn)行android:process 設(shè)置指定的進(jìn)程名稱。
當(dāng)然也可以給整個(gè)組件設(shè)置統(tǒng)一的進(jìn)程,這個(gè)也是在清單文件中配置。在<application>這個(gè)節(jié)點(diǎn)設(shè)置android:process屬性就可以了。

那么,什么情況下要去殺死進(jìn)程呢?依靠什么來殺死某些進(jìn)程,這就涉及到進(jìn)程的優(yōu)先級。Android系統(tǒng)在內(nèi)存不夠充足的情況下殺死進(jìn)程優(yōu)先級較低的進(jìn)程。Android中將進(jìn)程的優(yōu)先級分為5個(gè)層級(相當(dāng)于5中類型的進(jìn)程),主要依據(jù)對于用戶的需求程度來判斷的。

優(yōu)先級分類(從上到下進(jìn)程優(yōu)先級越來越低)

英文文檔在“sdk/docs/guide/components/processes-and-threads.html”

  • 前臺進(jìn)程
  • 可見進(jìn)程
  • 服務(wù)進(jìn)程
  • 后臺進(jìn)程
  • 空進(jìn)程
    下面一個(gè)一個(gè)來講:

    前臺進(jìn)程

前臺進(jìn)程有很多種情況,如果一個(gè)進(jìn)程屬于下面的任意一種情景,都屬于前臺進(jìn)程。

  • 情景一:該進(jìn)程中有Activity的onResume被調(diào)用,此時(shí)用戶正與這個(gè)Activity交互。
  • 情景二:該進(jìn)程中有一個(gè)Service,該Service綁定到當(dāng)前正在與用戶交互的Activity。
  • 情景三:該進(jìn)程中的通過startForegrount()啟動(dòng)的Service。
  • 情景四:該進(jìn)程中的Service正在執(zhí)行onCreate()、onStart()、onDestory()。
  • 情景五:該進(jìn)程中有正在執(zhí)行onReceiver()的BroadcastReceiver。

分析前臺進(jìn)程

  • 情景一:對于這種情況沒什么好說的,用戶正在與當(dāng)前的Activity進(jìn)行交互呢,不到萬不得已,不能殺死。
  • 情景二:現(xiàn)在先不講,下面講解過service后再來補(bǔ)充
  • 情景三:對于startForegrount()啟動(dòng)的服務(wù)是十分重要的,這種啟動(dòng)的服務(wù),就下面這種的:
startForegrount()啟動(dòng)的服務(wù)

后面我會告訴大家這種需求是如何實(shí)現(xiàn)的,慢慢來,不急。
很明顯,對于這種前臺進(jìn)程,我們幾乎不會見到被消失(被殺死),他是一只常駐內(nèi)存的,一直都是運(yùn)行在前臺的服務(wù)。

  • 情景四:一樣,現(xiàn)在先不講,下面講解過service后再來補(bǔ)充
  • 情景五:假設(shè)你已經(jīng)學(xué)過了BroadcastReceiver,就知道他的方法onReceiver(),當(dāng)收到廣播時(shí),系統(tǒng)就要進(jìn)行相應(yīng)的onReceiver中的操作。我好不容易收到一條廣播,現(xiàn)在就要處理廣播中的事情,你卻要把我干掉,我不服。所以對于這種情景的進(jìn)程是十分重要的,是會影響用戶的直觀體驗(yàn)的,這個(gè)必須提升為前臺進(jìn)程。

總結(jié):以上幾種情景的前臺進(jìn)程只有在內(nèi)存嚴(yán)重不足的情況下不到萬不得已才會被系統(tǒng)殺死,殺死的目的是為了及時(shí)響應(yīng)系統(tǒng)級別的需求,使得用戶界面不會出問題。

可見進(jìn)程

可見進(jìn)程指**沒有任何前臺組件、但仍會影響用戶在屏幕上所見內(nèi)容的進(jìn)程。 **

百度百科說:

可見(來自百度百科)

意思指:君子以成熟的德行為表率,時(shí)間久了就能看到他的這種行為。
無論是古文還是現(xiàn)代文,“可見”,有點(diǎn)朦朧的感覺,就像你跟她之間隔了一個(gè)玻璃一樣。雖然就在你眼前,可我卻觸碰不到你,(o)/~。
這里的可見進(jìn)程有兩種,但都是透露了一種朦朧感覺情況下的進(jìn)程

  • 情景一:該進(jìn)程的service綁定到了可見或者在前臺的Activity。
  • 情景二:當(dāng)前進(jìn)程中有Activity,但是不在不在前臺,卻可以看見。

分析

  • 情景一:(后面講解service時(shí)再講)
  • 情景二:靠,情景二什么情況?下面我就演示下:

兩個(gè)APP兩個(gè)進(jìn)程,分別對應(yīng)A、B。打開A后再打開BAPP,特殊之處在與B APP的Activity是透明的。

APP B的清單文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.asia.app_b">    
<application        
android:allowBackup="true"       
 android:icon="@mipmap/ic_launcher"     
  android:label="@string/app_name"     
   android:supportsRtl="true"  
      android:theme="@android:style/Theme.Translucent">   //設(shè)置APP B的Activity為透明的
     <activity android:name=".MainActivity" > 
           <intent-filter>              
  <action android:name="android.intent.action.MAIN" />             
   <category android:name="android.intent.category.LAUNCHER" />         
   </intent-filter>       
 </activity>  
  </application>
</manifest>

APP A中添加打開APP B的方法

APP A的MainActivity文件如下,主要添加了顯示變化的時(shí)間的功能。

MainActivity.class
onResume下的可見進(jìn)程

打開APP B 后,此時(shí)APP B是前臺進(jìn)程,前臺組件是APP B的所有組件。APP A 進(jìn)入了Pause狀態(tài),可見但是沒有獲取焦點(diǎn)。此時(shí)APP A是可見進(jìn)程,APP A沒有任何前臺組件、但仍會影響用戶在屏幕上所見內(nèi)容的。對于用戶來說,依然想看到APP A上的時(shí)間變化,對用戶來說APP A的進(jìn)程重要性僅次于APP B,也就是僅次于前臺進(jìn)程。
可見進(jìn)程也是十分重要的進(jìn)程,除非維持所有前臺進(jìn)程運(yùn)行時(shí)有危險(xiǎn)時(shí),系統(tǒng)才會干掉可見進(jìn)程。

總結(jié)可見進(jìn)程:沒有任何前臺組件、但仍會影響用戶在屏幕上所見內(nèi)容的進(jìn)程。

服務(wù)進(jìn)程

這個(gè)就是這篇文章的高潮,講解Service的內(nèi)容。該進(jìn)程中有通過startService啟動(dòng)的服務(wù),同時(shí)該服務(wù)的情況不屬于前臺進(jìn)程以及可見進(jìn)程。 服務(wù)進(jìn)程的重要性僅次于前臺進(jìn)程和可見進(jìn)程。這句話看起來是廢話,其實(shí)不然,因?yàn)樗竺孢€有兩個(gè)進(jìn)程。對于服務(wù)進(jìn)程而言,雖然他不會直接對用戶所關(guān)心的界面造成影響,但是有的時(shí)候做文件下載或者后臺播放音樂,是需要在這個(gè)進(jìn)程中進(jìn)行的。
可能有人問,下載文件我直接在Activity中開啟子線程不就可以了么?為什么需要在服務(wù)中進(jìn)行下載呢?
我們先在Activity中開啟一個(gè)主線程進(jìn)行模擬下載。

模擬下載代碼
開始下載->銷毀Activity->清空進(jìn)程

開始下載的時(shí)候一切正常,然后按下返回鍵,activity被銷毀,此時(shí)APP A在空進(jìn)程(進(jìn)程的一種)中,下載繼續(xù)。模擬內(nèi)存不夠充足,我清空了后臺運(yùn)行的APP A,此時(shí)下載停止了。很明顯的,下載文件不能因?yàn)槲仪蹇樟撕笈_運(yùn)行的APP就將下載停止了。谷歌提供的解決方案就是在服務(wù)進(jìn)程中進(jìn)行下載操作。這種進(jìn)程不會被輕易殺死。

注意:
開啟一個(gè)服務(wù),并不會直接開啟一個(gè)新的進(jìn)程(除非你指定了新的進(jìn)程),也不會開啟一個(gè)新的子線程。服務(wù)也是運(yùn)行在主線程中的,所以如果需要在服務(wù)中進(jìn)行耗時(shí)操作,需要在服務(wù)中開啟一個(gè)子線程去下載文件。

殺死服務(wù)進(jìn)程的可能性也較低,除非內(nèi)存不足以支撐前臺進(jìn)程、可見進(jìn)程的運(yùn)行。

總結(jié)服務(wù)進(jìn)程: 該進(jìn)程中有通過startService啟動(dòng)的服務(wù),同時(shí)該服務(wù)的情況不屬于前臺進(jìn)程以及可見進(jìn)程。

后臺進(jìn)程

該進(jìn)程包含對用戶不可見的Activity進(jìn)程(該Activity的onStop方法被調(diào)用)

分析后臺進(jìn)程

這種進(jìn)程不知道什么時(shí)候就會被系統(tǒng)干掉了,因?yàn)檫@下進(jìn)程不會直接影響用戶的直觀體驗(yàn),回收的目的為了供前臺進(jìn)程、可見進(jìn)程、服務(wù)進(jìn)程使用。
在手機(jī)中會有很多這種進(jìn)程,他們都被緩存在一個(gè)列表中。這個(gè)列表就是LRU列表。然后根據(jù)LRU(Least Recently Used 近期最少使用算法),將很久以前使用的進(jìn)程第一個(gè)殺掉,最后殺掉剛剛進(jìn)入后臺的進(jìn)程,保證剛剛最近被使用的進(jìn)程快速還原。
當(dāng)你把APP退到后臺,過一段時(shí)間再打開式,只要從引導(dǎo)頁進(jìn)入,說明這個(gè)進(jìn)程處于后臺進(jìn)程的時(shí)候被干了。。。

空進(jìn)程

沒有處于活動(dòng)狀態(tài)的任何組件所在的進(jìn)程

分析空進(jìn)程

剛才在服務(wù)進(jìn)程中講的在Activity中開啟子線程下載文件,退出APP后,該進(jìn)程就變成了空進(jìn)程。之所以保留這種進(jìn)程,是為了下載快速啟動(dòng)該進(jìn)程。這種進(jìn)程經(jīng)常被干掉。

此篇最后

Android中的五種進(jìn)程,前臺進(jìn)程、可見進(jìn)程、服務(wù)進(jìn)程、后臺進(jìn)程、空進(jìn)程?;局v完了,其中涉及到Service的在下篇文章中會引入。

有什么問題,不吝賜教O(∩_∩)O哈哈~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,034評論 25 709
  • 上篇我們講解了Android中的5中等級的進(jìn)程,分別是:前臺進(jìn)程、可見進(jìn)程、服務(wù)進(jìn)程、后臺進(jìn)程、空進(jìn)程。系統(tǒng)會按照...
    徐愛卿閱讀 3,980評論 6 33
  • 什么是進(jìn)程 進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單...
    晨起清風(fēng)閱讀 1,980評論 0 5
  • 引言 根據(jù)《算法》第4版。編寫紅黑樹。 理論 參見: 淺談算法和數(shù)據(jù)結(jié)構(gòu): 八 平衡查找樹之2-3樹 淺談算法和數(shù)...
    林灣村龍貓閱讀 1,844評論 0 1
  • 一直以來,我們都會尋找自己內(nèi)心的需求??墒亲约盒睦锵氲目偸桥c自己的行動(dòng)會相差很遠(yuǎn)。喝過很多的雞湯,卻不一定會做雞湯...
    鹿鹿無畏閱讀 828評論 2 51

友情鏈接更多精彩內(nèi)容