如何讓android的service一直在後台運行?
如何讓android的service一直在後台運行,即使activity已經被finish掉了和應用程序的主進程已經被用戶清掉了,我還讓這個服務在後台運行。另外,如果用戶關機後,重新啟動之後我也想這個服務就啟動。我嘗試了很多方法,剛一開始用localservice發現不行,又改用remoteservice,發現調用startservice後我的activity退掉之後,服務還在運行,但是我把該應用程序清了之後service就停止了。我想問一下各位做android的大哥,service除了在activity中啟動還有別的東西可以啟動service嗎?我上網查了說用Intent.ACTION_TIME_TICK這個廣播,可以實現在service停止掉之後重新啟動,但是那個廣播好像只能動態註冊,我在activity中的ontart中註冊後還得在ondestroy中解除,這是否意味著我activity沒有啟動這個廣播就不起作用了,如果這樣的話還是沒有達到目的。總之,我的服務是依賴於主進程而存在的,當我把應用程序關了之後,就是android顯示後台運行程序然後左滑關掉程序後,我的服務就不能運行了。但是微信和qq可以這樣,他們的程序沒運行但可以有進程和服務在後台運行,這是怎麼做的呢?
1. 把service和activity分開,讓service開機啟動。設置一個broadcast receiver接受開機信號,使用RECEIVE_BOOT_COMPLETED的permission, 然後啟動service。activity啟動後綁定到service上,通過ipc機制通信,acitivity結束後鬆綁。注意安裝後要手動啟動service,不會自動啟動,之後重啟手機後才會隨開機啟動。
2. 在內存低的時候系統會自動清理進程,這時候後台service可能會被殺掉。可以在onStartCommand中返回START_STICKY,這樣系統有足夠多資源的時候,就會重新開啟service。
3. 以上不需要NDK,直接用SDK開發就可以了。android 一直運行的後台服務是不存在的,而且也不是最佳實踐,因為一直運行的後台服務會耗費大量系統資源,影響其他程序的響應從而影響到用戶體驗。
題主問的是如何讓後台服務一直運行,我認為只有系統自帶的應用或者定製的系統應用才可以有這麼高的優先順序可以保持後台服務一直運行。如果是在非root的系統上的普通應用,只能是通過一些方法,讓用戶覺著後台服務一直運行。比如,監聽開機事件,顯式地啟動後台服務;啟動後台服務後給它設置「前台運行」的優先順序;定時任務來檢查後台服務是否在運行,不運行的話重新啟動它。
可以考慮使用如下幾種方案來達到一直運行的效果。1. 調用startForeground方法,android: Service vs SingleTop Activity moved to background2. 使用AlarmManager 發送定時任務 : Diamonds Are Forever. Services Are Not.更極端的例子,如果應用被幹掉了,定時任務(AlarmManager)這種方法確實不管用了,但是可以考慮給後台服務設置「前台」運行的優先順序這種方法。比如音樂播放器,在啟動播放服務後,通知欄會顯示一個播放進度的通知條,這個通知條是必須的,因為通過它才能使後台服務獲取到「前台」運行的優先順序從而避免被系統幹掉。這種做法也是官方推薦的做法。下面是官方文檔中的一些具體說明:說明一
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
說明二
Service | Android Developers(int, android.app.Notification)
Make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default services are background, meaning that if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You can set this flag if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.
其他參考資料
使用startForeground讓android服務前台運行android - startForeground() without showing notification有一種做法是開兩個進程來相互監督,一旦其中一個進程被停止,另一個檢測到後,立即或稍後重啟另一個進程。這裡可以效仿這種做法。可以開兩個進程,一個用來做前台,另一個負責運行服務,後者沒有activity,由前者初始化並啟動,這樣,當前台進程被關閉時,服務並不被關閉
我現在也遇到這個問題,我想樓主之所以出現這個問題的原因是,你在Activitiy中創建的Service運行在當前進程中,當你把這個Activitiy的進程殺掉之後,自然這個服務也就停止了。
所以我的建議是在startService的時候,讓這個Service運行在與該Activity不同的進程中(可以startService或者開機時創建一個新的進程)。實際上就是Linux裡面的進程操作。可以使用NDK開發,用C或者C++新建一個進程來運行自己的服務,並提高進程優先順序,避免被清理掉(我猜測QQ和微信的推送服務,或許是這麼實現的)。但是這涉及一個問題:你的應用是否應該常駐內存?內存長期被佔用會導致用電量的提升,所以非系統的應用一般都是可以在清理內存的時候被清理掉的(除了某某手機管家之類的應用,殺都沒法殺掉)。在framework層可以實現。做到rom里。
微信作為現在常用工具,你們沒有發現根本殺不死么?至少在許可權方面,我相信了一個叫白名單的東西確實存在!!!你們可以自己試一下,用微信的包名創建一個項目,打包以後不要設置app的圖片,一般的國產手機,裝完後自動識別為微信,圖標在沒設置的情況下自動變為微信默認圖標!!!微信作為一款即時通訊類的app,常駐後台確實無可奈何,但是你們可以看下,電量消耗比,微信、QQ所佔比例都是前幾名!!!對於用戶來說,耗電低,內存佔用少,這才是優化的方向
鄭強 說的對,基本上都不可行別問我為什麼,因為我都試過
是啊
應用層面上,是不可能完美做到後台持續運行的。
基本大廠的APP,都會根手機廠商合作了吧,在系統底層開白名單,忽略殺死某些APP。AlarmManager定時任務,也可能因為休眠狀態而終端。哪怕使用了RTC_WAKEUP類型。監聽系統廣播,我記得Android3.0以後,靜態註冊的廣播接收器,在程序已經死掉的情況下,是收不到廣播的了。 開機自動運行,不靠譜的地方在於,現在系統都有禁止開機啟動的設置了。最靠譜的辦法,還是推薦Android官方的,前台服務, Foregroud Service吧。
可惜,N多二逼的產品經理,會跑過來怒斥你:「我要持久運行,但不能在通知欄顯示這個通知!想辦法給我搞定!」有道理
貌似官方推薦用AlarmManager設置定時任務。官方文檔:https://developer.android.com/training/scheduling/alarms.html
前一陣子很流行的我要早睡app就是運行了一個service,要麼他是註冊了各種廣播事件,比如鎖屏啊,解鎖啊,之類的,要麼他是監測logcatAndroid, Detect when other apps are launched
經過驗證以上方法全部不可用,除非在底層開發
推薦閱讀:
※如何評價樂視 Cool 1 生態手機?
※一加手機好用嗎,適合學生黨嗎?
※為什麼蘋果這麼多人用?哪裡好?
※Android 4.4 和 Android 7.0 的區別是什麼?
※如何評價新版知乎 2.0 for Android?