眾所周知, Service是跑后台的. 但是有些Rom廠商把一鍵清理做的真是太好用了, 以至於一鍵清理變成了一種習慣, Service已經變的不再是Service了. 那為什么像諸如360, 微信, QQ...卻可以傍山傍水.哦, 用錯詞了. 大家懂的. .
言歸正傳, android的系統進程分為五個等級, Foreground Process(前台進程), Visible Process(可見進程), Service Process(服務進程), Background Process(后台進程), Empty Process(空進程), Service的進程處於第三個位置. 系統的回收會從低到高依次回收, 所以我們必須提高Service的等級, 仔細看Service的API會發現這么個方法.
public final void startForeground (int id, Notification notification)
這個方法是從API 5開始的, 又說費話了. 但是用了之后會發現通知欄會彈出個通知, 不彈通知人家讓你傳Notification干嘛, 哦, 好吧, 我又NC了. 這就很好的解釋了360和LBE這些軟件的那個通知了. 那QQ,微信為什么沒有呢. 方法是死的, 人是活的.
我們可以這樣.
private void startForegroundCompat() { try { if (Build.VERSION.SDK_INT < 18) { Log.v(TAG, "startForgroundCompat"); startForeground(1120, new Notification()); } } catch (Exception e) { if (DEBUG) Log.e(TAG, "", e); } }
為什么要低於版本18呢, 那你這句就問的就是廢話了. 有Bug唄, 開個玩笑, 在版本18以及以上, 會彈出個默認的通知, so, 要低於版本18.
那有人可能又想, 那我們寫成這樣呢.
startForeground(1120, null);
當然也不行了, 要是行還new個空的干嘛, 這樣會報錯滴.
如果這樣做之后, 你會發現一鍵清理對你的Service是完全不起作用的(再也沒有那該死的正在重新啟動了, 你這么吊, 你經理知道嗎, 啊. 啊). 你可以哈哈大笑了, 總算解決了個殘留很久的問題了. 但是,但是...MIUI必須在自啟動管理里允許, 否則下文一切都是扯淡.
網上還有說通過startCommand的返回值讓Service是否重新啟動, 我覺着這樣很不好.
第一, 用戶清理這是一對多的關系,也許用戶並不想清理你的程序呢(當然這概率有點小. 你又不是微信, 人家是拿到船票的人, 跟你我屌絲能一樣嗎), 所以這樣做的必要是有的. 好像跟上面的問題沒多大關系啊.
其二, 我想清理, 結果你還重新啟動, 哇靠, 這什么APP, 這么流氓, 關鍵我都定位到你那個詳情了, 點停止你還啟, 點停止你還啟...比如那個類微信...(當然也可以清理, 等它重新啟動的時候再停止一次, 就See Bye了)
最后, 咱最終還是本着決定權在用戶手里的原則, 你要是真的讓我走, 我絕不死機白咧, 但是我得知道, 你真的指的是我, 走, 也要走的唯一!
按常理的話, 題目的解釋到這里就完成了.
但是我這人吧, 就喜歡多做一點點. 永遠超出別人的預期. 吼哈....
有的人會想, 那我API18以后怎么辦, 我, 我, 我也不知道撒...
但是我可以保證的是, 只要用戶不刪你的APP, 你的服務就可以一直是活動的.
<receiver android:name=".NotifyReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.TIME_SET" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.DATE_CHANGED" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.TIMEZONE_CHANGED" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:scheme="package" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.MEDIA_BAD_REMOVAL" /> <action android:name="android.intent.action.MEDIA_EJECT" /> <action android:name="android.intent.action.MEDIA_MOUNTED" /> <action android:name="android.intent.action.MEDIA_REMOVED" /> <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED" /> <action android:name="android.intent.action.MEDIA_SCANNER_STARTED" /> <action android:name="android.intent.action.MEDIA_SHARED" /> <action android:name="android.intent.action.MEDIA_UNMOUNTED" /> <data android:scheme="file" /> </intent-filter> </receiver>
你注冊這么個廣播接收器, 在里面啟動你的Service(當然啟動的時候最好判斷下是否啟動), 除非用戶不操作手機, 不安裝, 不卸載, 網絡環境一直不變化. 否則, 嘿嘿
What, 我這是在扇自己的臉嗎. 我只是說有這么個方案, 當然不太建議大家去這么做, 簡直太流氓了, 反正我是這么做了. 需求讓人迷失自己!!! 迷失 Noooooooo, 程序員是沒有自己的.
最后歡迎大家來到群:215621863 , 討論有技術, 沒技術的.
