優化後臺推送的service,減小被殺死的概率

作以前大概思路是:基本參考的原理是官方對內存清理時的5個優先級別,製造出一個單獨的接收push的進程來放push service。涉及到的問題包括官方的說明、service啓動相關原理,一個app兩個進程的知識,兩個進程間的通訊。html

 ---------------------mark:T9200,HM1S的代碼:NotifyService每5秒發parseReceiver的通知。網絡變化主動stop ParseService。C8825增長了解鎖時啓動NotifyService。java

參考1:微信的兩個進程:http://www.cnblogs.com/GIS-Dream/p/3246534.htmlandroid

參考2:android進程間通訊:http://blog.csdn.net/victory08/article/details/8696252git

參考3:Application有一個override方法叫onLowMemoryshell

參考4:官方:http://developer.android.com/guide/components/processes-and-threads.html緩存

參考5:service 的通訊有三種方式:Extending the Binder class;Using a Messenger;Using AIDL安全

          Extending the Binder class  This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.微信

參考6:parse是依賴於gcm的。從manifest能夠看出來。國行手機閹割掉的主要是這四個:【1】GoogleServicesFramework.apk(此爲必需!要用google服務就得裝!)
  【2】GoogleContactsSyncAdapter.apk和【3】GoogleCalendarSyncAdapter.apk可根據本身須要安裝,不用聯繫人和日曆同步則能夠不裝,【4】Google Play .APK若是    你想用上google商店----------------這4個APK合起來就是google的服務框架,安裝完這幾個APK就能夠兼容谷歌基本全部的應用。網絡

    GCM的問題:「先不提4.0以前必須登陸google帳戶才能用,gcm容易常常被牆,容易被rom刪掉。到達率50%仍是80%仍是90%又如何?不是100%就無法用。即便100%    的android手機都有,偶爾牆一下也受不了。app

參考7:手機360衛士的一些牛B權限:

  安全類:1,修改系統設置;2,在其餘應用之上進行繪圖;3,對正在運行的應用從新排序(移動到前臺或者後臺reorder other app);4,直接安裝應用;5,從新設置外撥電話的路徑;

   隱私類:1,檢索正在運行的應用;

  其它類:1,修改安全系統設置;2,關閉其餘應用 ;3,刪除全部應用緩存數據;4,強制關閉後臺應用;5,查閱敏感日誌數據;

 

  手機360衛士須要有root權限才能作的是:自啓動軟件管理,軟件權限監控等。全部的權限都定義在android.Manifest類中。ActivityManager類有moveTaskToFront,   killBackckProcess,getRunningAppProcess等功能。

 

參考8:

    官網:

    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.)

參考9:stack網上一篇討論:http://stackoverflow.com/questions/7142921/usage-of-androidprocess

首先,關於manifest中的一些細節還須要挖掘一下。http://developer.android.com/guide/topics/manifest/manifest-element.html#uid

而後,官網的Training模塊關於多Process的討論。http://developer.android.com/training/articles/memory.html#MultipleProcesses

還有,官網的Tools模塊關於Investigate RAM的介紹

參考10:出現了新的問題,當定義了新的process,新的process會Replicate不少原process的內存過來,致使一個空的service也要15M的內存。而原process內存未減小。

一方面嘗試主動去控制新process中的內容,另外一方面嘗試主動控制activity資源的在後臺時的釋放。

 

參考11:把activity context傳遞給view,意味着view擁有一個指向activity的引用,進而引用activity佔有的資源:view hierachy, resource等。

避免這種內存泄露的方法是避免activity中的任何對象的生命週期長過activity,避免因爲對象對 activity的引用致使activity不能正常被銷燬。咱們可使用application context。application context伴隨application的一輩子,與activity的生命週期無關。application context能夠經過Context.getApplicationContext或者Activity.getApplication方法獲取

避免context相關的內存泄露,記住如下幾點:
1. 不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity自己生命週期是同樣的
2. 對於生命週期長的對象,可使用application context
3. 避免非靜態的內部類,儘可能使用靜態類,避免生命週期問題,注意內部類對外部對象引用致使的生命週期變化

【其餘的相關事項】

1)在SDK中的DigitalClock Widget ,由於DigitalClock要註冊一個observer,因此會用把載上DigitalClock widget的Activity做爲那個observer。但在SDK的DigitalClock是有一個Bug的,由於在DigitalClock 的onDetachedFromWindow中是沒有unregister 那個observer的。 解決方法是本身寫一個DigitalClock。詳情請看附上的代碼(DigitalClockNew.java)。

2)在SDK中的Toast的function makeText 是要求傳一個Context的,但在Toast的代碼中,這個Context是會用作callback上。若是是傳Activity做爲那個 Context的話,那會發生memory leak的問題。解決方法是傳 Application Context,而不是ActivityContext。

【如何查看Memory leak的問題】

若是懷疑有memory leak的問題,可先執行那個apk在emulator上,而後在PC上執行adb shell,,而後執行ps,查看你的process 的pid。

在apk上執行有memory leak可疑的動做後,能夠作下面的診斷

1.  執行 dumpsys meminfo <pid>

這個指令顯示pid的memory資料。注意是 Activity的 數量,若是數量是不斷上升,那就是有memory leak。 注意,由於在未執行Gargage Collect前,Activity是不會被釋放的。能夠在DDMS上執行手動的Gargage Collect。

2. 把process 的memory dump 出來,看memory leak的所在

先執行 chmod 777 /data/misc,而後執行 kill -10 <pid> ,在 /data/misc 上會看到那個pid 的memory leak,(如heap-dump-tm1265266619-pid1673.hprof )

adb pull ( 如adb pull /data/misc/ heap-dump-tm1265266619-pid1673.hprof 1673.hprof )把這個檔案拷回電腦上。

而後,用在PC上執行hprof-conv (如hprof-conv  1673.hprof  1673_a.hprof) 把那個拷回來的hprof轉換成 Eclipse Memory Tool 能夠支持的格式。

用Eclipse Memory Tool (http://www.eclipse.org/mat/), 打開轉換了的memory dump。 在Eclipse Memory Tool 上,按OQL,輸入 「select * from instanceof android.app.Activity」 , 這個指令能夠找因此在系統上是android.app.Activity 的 instance。(詳見下圖)

若是在object的旁帶有「Unknown」的話,那object是能夠被Gargage Collect的。要看其餘的object是什麼緣由不能夠被Gargage Collect 的話,能夠在那個object上right-click,而後選Path to GC Roots, exclude weak/soft reference 。 (weak 和soft reference 都是能夠被VM查到的,因此是能夠Gargage Collect的。)

在Path to GC Roots 中,能夠看到WidgetManagerHome 是由於Toast中的inner class TN 把 這個WidgetManagerHome抓住了。

(關於查找leaks,參考下這個http://blog.crowdint.com/2013/10/02/fixing-memory-leaks-in-android-applications.html)

==============================================================================

 

記錄:

  通過多日的研究,這裏簡單記錄一下。

  1,結束service時,不會結束進程。service被殺掉的話,process其實還在。因此能夠沒必要讓service的onDestroy中自動重啓。

  2,內存緊張時進程被殺掉後,若是service有自動重啓,那麼整個進程都會執行一次新的啓動過程。

  2.5,而service沒有自動啓動的話,內存緊張殺進程還,仍是重啓了進程,是否是代碼其餘地方有處理---此現象只在紅米上設置容許自動重啓的時候會出現。

  3,service被結束後,其Thread變量還在運行,why?

  4,onTrimMemory調用可能會很頻繁,不可作過多處理

  5,沒有activity有Service的進程更安全。可是:xxx增長一個進程,會複製不少context環境進去,有可能佔用更大的內存

  6,叮咚在內存屢次告急(80分)時,還不釋放activity,應該是有內存泄露,沒法回收。

  7,叮咚的MainDingtone有泄露,即便主動調用了finish()方法,仍是沒法釋放activity的資源

如今要解決的問題是:1,could not construct writer是否是有切換網絡的緣由?2,如何主動的把activity資源釋放掉?3,嘗試監聽網絡狀態,主動關掉parseService,讓其自動重啓。

 

 

注:

已優化:

  按鍵音播放;

其餘待優化:

  UI緩存跳轉的優化;數據模型的抽象共用優化;Activity,View等抽象共用優化;

相關文章
相關標籤/搜索