導航:首頁 > 操作系統 > androiddrawable回收

androiddrawable回收

發布時間:2023-01-25 14:39:50

⑴ 想讓android應用常駐後台,不被殺死,各位大神有什麼高招

方法: 對於一個service,可以首先把它設為在前台運行: public void MyService.onCreate() { super.onCreate(); Notification notification = new Notification(android.R.drawable.my_service_icon, "my_service_name", System.currentTimeMillis()); PendingIntent p_intent = PendingIntent.getActivity(this, 0, new Intent(this, MyMainActivity.class), 0); notification.setLatestEventInfo(this, "MyServiceNotification, "MyServiceNotification is Running!", p_intent); Log.d(TAG, String.format("notification = %s", notification)); startForeground(0x1982, notification); // notification ID: 0x1982, you can name it as you will. } 重要設置------------------------------- 相較於/data/app下的應用,放在/system/app下的應用享受更多的特權,比如若在其Manifest.xml文件中設置persistent屬性為true,則可使其免受out-of-memory killer的影響。如應用程序'Phone'的AndroidManifest.xml文件: <application android:name="PhoneApp" android:persistent="true" android:label="@string/dialerIconLabel" android:icon="@drawable/ic_launcher_phone"> ... </application> 設置後app提升為系統核心級別,任何情況下不會被kill掉, settings->applications裡面也會屏蔽掉stop操作。 這樣設置前的log: Proc #19: adj=svc /B 4067b028 255:com.xxx.xxx/10001 (started-services) # cat /proc/255/oom_adj 設置後的log: PERS #19: adj=core /F 406291f0 155:com.xxx.xxx/10001 (fixed) # cat /proc/155/oom_adj -12 # 這是CORE_SERVER_ADJ 註:init進程的oom_adj為-16(即SYSTEM_ADJ): cat /proc/1/oom_adj Android相關部分分析: 在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下的代碼: final ProcessRecord addAppLocked(ApplicationInfo info) { ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); if (app == null) { app = newProcessRecordLocked(null, info, null); mProcessNames.put(info.processName, info.uid, app); updateLruProcessLocked(app, true, true); } if ((info.flags&(ApplicationInfo.FLAG_SYSTEMApplicationInfo.FLAG_PERSISTENT)) == (ApplicationInfo.FLAG_SYSTEMApplicationInfo.FLAG_PERSISTENT)) { app.persistent = true; app.maxAdj = CORE_SERVER_ADJ; // 這個常數值為-12。 } if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application", app.processName); } return app; } 可見要想成為core service (即app.maxAdj = CORE_SERVER_ADJ(-12)),應用程序需要FLAG_SYSTEM和FLAG_PERSISTENT兩個標志,FLAG_SYSTEM指的是應用位於/system/app下,FLAG_PERSISTENT就是指persistent屬性。 而對於frameworks/base/services/java/com/android/server/SystemServer.java,則調用 ActivityManagerService.setSystemProcess(); 把自己的 app.maxAdj 設置成SYSTEM_ADJ,即-16。 原理: Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先順序自動進行進程的回收。由此帶來三個問題: 1) 回收規則: 什麼時候回收與回收哪一個? 2) 避免誤殺: 如何阻止被回收? 3) 數據恢復與保存: 被回收了怎麼辦? Android將進程分為6個等級,它們按優先順序順序由高到低依次是: 1.前台進程( FOREGROUND_APP) 2.可視進程(VISIBLE_APP ) 3. 次要服務進程(SECONDARY_SERVER ) 4.後台進程 (HIDDEN_APP) 5.內容供應節點(CONTENT_PROVIDER) 6.空進程(EMPTY_APP) 特徵: 1.如果一個進程裡面同時包含service和可視的activity,那麼這個進程應該歸於可視進程,而不是service進程。 2.另外,如果其他進程依賴於它的話,一個進程的等級可以提高。例如,一個A進程里的service被綁定到B進程里的組件上,進程A將總被認為至少和B進程一樣重要。 3.系統中的phone服務被劃分到前台進程而不是次要服務進程. 在android中,進程的oom_adj值也就代表了它的優先順序。oom_adj值越高代表該進程優先順序越低。文件/init.rc中有以下屬性設置: setprop ro.FOREGROUND_APP_ADJ 0 setprop ro.VISIBLE_APP_ADJ 1 setprop ro.SECONDARY_SERVER_ADJ 2 setprop ro.HIDDEN_APP_MIN_ADJ 7 setprop ro.CONTENT_PROVIDER_ADJ 14 setprop ro.EMPTY_APP_ADJ 15 /init.rc中,將PID為1的進程(init進程)的oom_adj設置為SYSTEM_ADJ(-16): # Set init its forked children's oom_adj. write /proc/1/oom_adj -16 查看本機設置: cat /sys/mole/lowmemorykiller/parameters/adj 0,1,2,7,14,15 回收時機: 文件/init.rc中: setprop ro.FOREGROUND_APP_MEM 1536 // 6M setprop ro.VISIBLE_APP_MEM 2048 // 8M setprop ro.SECONDARY_SERVER_MEM 4096 // 16M setprop ro.HIDDEN_APP_MEM 5120 // 20M setprop ro.CONTENT_PROVIDER_MEM 5632 // 22.4M setprop ro.EMPTY_APP_MEM 6144 // 24M 這些數字也就是對應的內存閾值,一旦低於該值,Android便開始按順序關閉相應等級的進程。 注意這些數字的單位是page: 1 page = 4 kB。所以上面的六個數字對應的就是(MB): 6,8,16,20,22,24。 查看現在的內存閾值設置: cat /sys/mole/lowmemorykiller/parameters/minfree 要想重新設置該值(對應不同的需求): echo "1536,2048,4096,5120,15360,23040">/sys/mole/lowmemorykiller/parameters/minfree 這樣當可用內存低於90MB的時候便開始殺死"空進程",而當可用內存低於60MB的時候才開始殺死"內容供應節點"類進程。 具體的回收實現在ActivityManagerService.java中的函數trimApplications(): 1.首先移除package已被卸載的無用進程; 2.基於進程當前狀態,更新oom_adj值,然後進行以下操作: 1) 移除沒有activity在運行的進程; 2) 如果AP已經保存了所有的activity狀態,結束這個AP。 3. 最後,如果目前還是有很多activities 在運行,那麼移除那些activity狀態已經保存好的activity。 更新oom_adj的值: 在ActivityManagerService.java文件的ComputeOomAdjLocked() 中計算出進程的oom_adj,例如: if (app == TOP_APP) { // The last app on the list is the foreground app. adj = FOREGROUND_APP_ADJ; app.adjType = "top-activity"; } Android kernel中的low memory killer Android的Low Memory Killer根據需要(當系統內存短缺時)殺死進程釋放其內存,源代碼在kernel/drivers/misc/lowmemorykiller.c中。簡單說,就是尋找一個最合適的進程殺死,從而釋放它佔用的內存。 最合適的進程是: • oom_adj越大 • 佔用物理內存越多 一旦一個進程被選中,內核會發送SIGKILL信號將之殺死: for_each_process(p) { …… if(selected == NULL p->oomkilladj > selected->oomkilladj (p->oomkilladj == selected->oomkilladj && tasksize > selected_tasksize)) { selected = p; } } if(selected != NULL) { force_sig(SIGKILL, selected); } 查看LRU列表:adb shell mpsys activity 當activitydemo在前台時: 包含Service的進程的優先順序比較高,在computeOomAdjLocked中將其分為了兩小類: static final int MAX_SERVICE_INACTIVITY = 30*60*1000; if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { if (adj > SECONDARY_SERVER_ADJ) { adj = SECONDARY_SERVER_ADJ; app.adjType = "started-services"; app.hidden = false; } } if (adj > SECONDARY_SERVER_ADJ) { app.adjType = "started-bg-services"; } 完全讓進程不被kill是不可能的,我們可以通過一些操作,使進程被kill的幾率變小: 1) 提高進程的優先順序: * 後台操作採用運行於前台的Service形式,因為一個運行著service的進程比一個運行著後台activity的等級高; * 按back鍵使得進程中的activity在後台運行而不是destory,需重載back按鍵(沒有任何activity在運行的進程優先被殺). * 依賴於其他優先順序高的進程; 2) 強制修改進程屬性: * 在進程中設置:setPersistent(true); * 在Manifest文件中設置(如上)。

⑵ 怎麼給bitmap賦值 android

Bitmap是Android系統中的圖像處理的最重要的類之一。用它可以獲取圖像文件信息,對圖像進行旋轉,剪切,放大,縮小等操作。

Bitmap代表一張點陣圖,使我們在開發中常用的資源,下面就對Bitmap進行簡單的介紹。

Bitmap的獲取方法:

1、使用BitmapDrawable

BitmapDrawable里封裝的圖片就是一個Bitmap對象,我們要把Bitmap包裝成BitmapDrawable對象,可以調用BitmapDrawable的構造方法:

BItmapDrawbale drawable = new BItmapDrawable(bitmap);

如果要獲取BitmapDrawable所包裝的Bitmap對象,則可調用BitmapDrawable的getBitmap()方法:

Bitmap bitmap = drawbale.getBitmap();

2、Bitmap提供了一些靜態方法來創建Bitmap對象(僅列舉幾個):

createBitmap(Bitmap source,int x,int y,int width,int height):從原點陣圖source的指定坐標(x,y)開始,從中挖取寬width,高heigtht的一塊出來,創建新的Bitmap對象。

createScaledBitmap(Bitmap source,int width,ing height,boolean fliter):對源點陣圖進行縮放,縮放稱寬width,高heigth的新點陣圖。

createBitmap(int width,int height,Bitmap.Config config):創建一個寬width,高height的可變的新點陣圖。

createBitmap(Bitmap source, int x,int y,int width,int height ,Matrix m,boolean fliter):從源點陣圖source的指定坐標(x,y)開始,挖取寬width,高height的一塊來,創建新的Bitmap對象,並按照Matrix指定的規則進行變換。

3、通過對資源文件的解析獲取Bitmap對象

在這里就要用到BitmapFactory這個工具類,提供的方法如下:

decodeByteArray(byte[] data, int offset,int length):從指定位元組數組的offset位置開始,將長度為length的位元組數據解析成Bitmap對象。

decodeFIle(String pathName):從pathName指定的文件中解析、創建Bitmap對象。

decodeFileDescriptor(FileDescriptor fd):用於從FileDescriptor對應的文件中解析、創建Bitmap對象。

decodeResource(Resource res,int id):用於根據給定的資源ID從指定的資源文件中解析、創建Bitmap對象。

decodeStream(InputStream is):用於從指定輸入流中介解析、創建Bitmap對象。

但是,在系統不斷的解析、創建Bitmap的過程中,可能會由於內存小或其他原因,導致程序運行時發生OutOfMemory錯誤。

為此,Android為Bitmap提供了內存回收方法:

void recycle():強制回收Bitmap對象。

還有用於判斷Bitmap 對象是否被回收的方法:

boolean isRecycle();

如果Android應用需要訪問系統相冊,都需要藉助BitmapFactory解析、創建Bitmap對象。

4 從安卓無憂中看bitmap的幾種例子,下面是載入bitmap的例子,可以看裡面的源碼


如果您對答案滿意,請您關注一下名字中微博。

⑶ android中Drawable可以內存釋放嗎

用完調用recycle,切記如果recycle後在使用這個drawable對象會出問題,另外聲明drawable對象時使用弱引用,或者縮放處理。以減少所佔內存空間。希望有高手繼續補充。

⑷ Android開發問題怎麼解決

  1. R.java消失或解析異常

  2. 自定義title欄

  3. SQLite isFirst和isBeforeFirst方法的區別

  4. eclipse刪除空行

  5. getX()和getRawX()的區別

  6. imagView居中顯示問題

  7. synchronized引發了 java.util.

  8. 獲取隨機顏色

  9. 去掉Activity的標題欄,全屏顯示

  10. 如何修改應用名稱及應用圖標

  11. 關於調試方法

  12. Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

  13. android.content.res.Resources.loadXmlResourceParser

  14. android.content.res.Resources$NotFoundException

  15. 交互性的button定義的方法

  16. 在超級終端中執行程序報錯-Permission deny

  17. 從svn導入工程項目有驚嘆號

  18. 從svn導入工程項目有驚嘆號

  19. 首次進入帶有EditText的Activity不自動彈出軟鍵盤,再次點擊才彈

  20. Gallery中OnItemClickListener與OnItemSelectedListener的區別

  21. Eclipse中簽名導出apk崩潰,手動簽名

  22. android.view.InflateException: Binary XML file line #異常的解決

  23. 將assets文件夾中的壓縮包拷貝到sdcard中(不限大小)

  24. 判斷是否有root許可權

  25. 最簡單的Root 模擬器的方法

  26. 新版ADT開啟eclipse提示 "Running Android Lint" has encountered a problem

  27. 新版ADT開啟eclipse提示cannot open libstdc++.so.6..

  28. 無法升級ADT

閱讀全文

與androiddrawable回收相關的資料

熱點內容
義隆單片機視頻教程 瀏覽:383
cad安裝卡在解壓 瀏覽:615
編程精靈g540 瀏覽:256
手機文檔解壓之後解壓包去哪兒了 瀏覽:923
java中網路編程重要嗎 瀏覽:683
如何登錄別人的伺服器 瀏覽:626
調度系統軟體python 瀏覽:205
微信大轉盤抽獎源碼 瀏覽:497
壓縮機損壞的表現 瀏覽:862
同步數據伺服器怎麼用 瀏覽:634
163郵箱伺服器的ip地址 瀏覽:50
伺服器跟域是什麼 瀏覽:128
rails啟動命令 瀏覽:465
logistic命令怎麼用 瀏覽:738
c語言點滴pdf 瀏覽:747
linuxrtc編程 瀏覽:258
linux打包並壓縮命令 瀏覽:644
aes加密的證書格式 瀏覽:99
oracledbcalinux 瀏覽:844
酬勤任務app怎麼被特邀 瀏覽:199