Android性能優化-App后臺優化

原文鏈接?Background Optimizations

前言

后臺進程是內存和電池敏感的。一個隱式的broadcast可能會啟動很多監聽它的后臺進程,即使這些進程可能做得工作不多。這可能丟設備性能和用戶體驗都有比較大的影響。

為了緩解這種問題,7.0(API 24)做了以下限制:

  • Target為 Android 7.0 (API level 24)的App,將不會再收到在mainfest中注冊的?CONNECTIVITY_ACTION廣播。運行中的App仍然可以在Main Thread中通過Context.registerReceiver()注冊?CONNECTIVITY_CHANGE?廣播來監聽
  • App 將不能夠發送或者接收?ACTION_NEW_PICTURE?or?ACTION_NEW_VIDEO。這種優化會影響到所有的app,不僅是target為Android7.0的設備。`

因此如果你使用了這些intennt,應該盡快的移除對它們的依賴,以便你的app可以在Target為Android 7.0的設備上正常運行。Android框架提供了幾種解決方案去減小對這些隱式廣播的依賴。比如,JobScheduler?and?GcmNetworkManager提供了強健的機制去調度特定情況下的網絡操作。比如,你也可以使用JobScheduler去響應content provider的變化。JobInfo對象封裝了JobScheduler用于調度job的參數。當滿足指定的條件的時候,系統會通JobService過執行該job。

這篇文章將會告訴你如何使用替代的方法,比如JobScheduler去為你的app做這些限制的適配。

一 CONNECTIVITY_ACTION的限制

上面提到,Android 7.0 (API level 24) 將不再能夠收到mainfest中注冊的?CONNECTIVITY_ACTION?廣播。Android框架中已經提供了幾種替代方案,如何選擇依賴于你的具體實現。

注意:一個通過?Context.registerReceiver()注冊的BroadcastReceiver?在app運行期間是可以繼續收到廣播的。

在不可預測的網絡的情況下調度Network Jobs

當使用?JobInfo.Builder?類構建?JobInfo對象的時候, 通過?setRequiredNetworkType()?方法并傳遞JobInfo.NETWORK_TYPE_UNMETERED參數。下面的示例代碼演示了當設備連接到一個未知的網絡并且是在充電的時候,去調度一個service去執行的情景:

public static final int MY_BACKGROUND_JOB = 0;
...
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo job = new JobInfo.Builder(
MY_BACKGROUND_JOB,
new ComponentName(context, MyJobService.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(true)
.build();
js.schedule(job);
}

當以上條件滿足的時候,app就會收到一個回調去執行指定的JobService.class中的onStartJob()方法,更多?JobScheduler實例可參考?JobScheduler sample app.

使用GMSCore service的應用,并且target是5.0或者以下的,可以使用?GcmNetworkManager?并指定?Task.NETWORK_STATE_UNMETERED。

在APP運行期間監測網絡連接

運行期間的App仍然可以監聽CONNECTIVITY_CHANGE?,但是,?ConnectivityManager?提供了更多強大的方法在特定網絡條件滿足的時候去觸發一個回調。

NetworkRequest對象定義了NetworkCapabilities相關網絡回調的參數,你可以通過NetworkRequest.Builder類構建NetworkRequest對象,registerNetworkCallback(),然后將NetworkRequest傳遞對象到系統中去。當網絡條件滿足的時候,app就會受到一個回調去執行定義在?ConnectivityManager.NetworkCallback中的?onAvailable()方法。

App會一直接收注冊的回調,除非app退出或者調用unregisterNetworkCallback()方法。

二 NEW_PICTURE 和 NEW_VIDEO 的限制

Android 7.0 (API level 24),中,app將不能夠發送和接收這兩個廣播。當幾個不同的app必須喚醒設備去處理一個新的Image或者video的時候,這樣的限制可以改善性能和用戶體驗的影響。Android 7.0 (API level 24) 擴展了?JobInfo?和?JobParameters來提供一種替代方案。

新的JobInfo方法

為了讓content URI的變化去觸發job,Android 7.0 (API level 24)擴展了?JobInfo?的以下方法:

  • JobInfo.TriggerContentUri()

? 封裝了contentn URL變化需要的參數

  • JobInfo.Builder.addTriggerContentUri()

    傳遞一個?TriggerContentUri?對象給JobInfo。一個ContentObserver?監測器封裝的content URI。如果這里有多個TriggerContentUri?對象關聯到某個job上,只要其中某個URI變化,系統都會觸發回調事件。

TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS?標志在任何給定URI的子集有變化的時候,都會觸發job。該標志對應于傳遞給registerContentObserver()notifyForDescendants參數。

注意:?TriggerContentUri()?cannot be used in combination with?setPeriodic()?or?setPersisted(). To continually monitor for content changes, schedule a new?JobInfo?before the app’s?JobService?finishes handling the most recent callback.

注意TriggerContentUri()?不能夠和?setPeriodic()?或者?setPersisted()一起使用。為了持續地監測content 的變化,可以在JobService?處理完最近的回調之前去調度一個新的JobInfo。

下面的代碼演示了當系統上報一個MEDIA_URI contentURI的時候,調度一個job的場景:

public static final int MY_BACKGROUND_JOB = 0;
...
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(
MY_BACKGROUND_JOB,
new ComponentName(context, MediaContentJob.class));
builder.addTriggerContentUri(
new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
js.schedule(builder.build());
}

當系統上報指定的conent URI(s),你的app會收到一個回調和一個傳遞給onStartJob()方法( 在MediaContentJob.class中)的?JobParameters?對象。

新的JobParameter方法

Android 7.0 (API level 24)也擴展了JobParameters允許app接收有用的信息,該信息包含了具體是哪些content authorities 和 URIs 觸發了job。

  • Uri[] getTriggeredContentUris()

返回一個觸發了該Job的URIs數組。如果沒有URIs觸發job,或者URIs的數量大于50,那么該數組將為null(有可能job是由于其它原因觸發,比如一個deadline)。

  • String[] getTriggeredContentAuthorities()

Returns a string array of content authorities that have triggered the job. If the returned array is not?null, use?getTriggeredContentUris()?to retrieve the details of which URIs have changed.

The following sample code overrides the?JobService.onStartJob()?method and records the content authorities and URIs that have triggered the job:

返回一個觸發了該Job的content authorities數組。如果返回的數組不為null,可以使用?getTriggeredContentUris()方法獲取URIs變化的具體信息。

下面的代碼復寫了?JobService.onStartJob()?方法,并且記錄了觸發job的 content authorities 和URIs :

@Override
publicboolean onStartJob(JobParametersparams){
StringBuilder sb =newStringBuilder();
sb.append("Media content has changed:\n");
if(params.getTriggeredContentAuthorities()!=null){
sb.append("Authorities: ");
boolean first =true;
for(String auth :
params.getTriggeredContentAuthorities()){
if(first){
first =false;
}else{
sb.append(", ");
}
sb.append(auth);
}
if(params.getTriggeredContentUris()!=null){
for(Uri uri :params.getTriggeredContentUris()){
sb.append("\n");
sb.append(uri);
}
}
}else{
sb.append("(No content)");
}
Log.i(TAG, sb.toString());
returntrue;
}

三 Further Optimizing Your App

為低內存設備或者在低內存條件做優化,可以提升系能和用戶體驗。移除對后臺的service的依賴和靜態方式注冊的隱式廣播,可以幫助你的app在這樣的設備上運行的更好。盡管7.0上采取了一些措施減少了這些問題,但還是建議去優化app,即使在完全沒有使用后臺進程的情況也可以正常運行。

Android 7.0 (API level 24)引入了一些?Android Debug Bridge (ADB)?命令,可以幫助你測試app在禁止后臺進程的情況下app的行為:

  • 模擬隱式廣播和后臺service不可用的情況,可以使用下面的命令

    $ adb shell cmd appops set RUN_IN_BACKGROUND ignore

  • 重新開啟隱式廣播和后臺service

    $ adb shell cmd appops set RUN_IN_BACKGROUND allow

來源:http://www.lightskystreet.com/2016/10/16/android-optimize-background/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456465.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456465.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456465.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習之決策樹與隨機森林

目錄1、了解熵、條件熵、互信息的概念及公式1.1、熵1.2、條件熵1.3、信息增益/互信息 2、了解決策樹2.1、了解決策樹的概念和特點以及和熵的關系2.2、了解樹生成的過程2.3、了解決策樹三種算法的區別2.4、了解決策樹的損失函數2.5、了解解決決策樹過擬合的方法2.6、了解后剪枝的…

JSON(JavaScript Object Notation) 格式

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 它使得人們很容易的進行閱讀和編寫。同時也方便了機器進行解析和生成。JSON采用完全獨立于程序語言的文本格式,但是也使用了類C語言的習慣。 json是 JavaScript Object Notation 的首字母縮寫&…

synchronized 的理解

第一種:package com.ucmed.zsyy.util;/*** Created by ucmed on 2017/2/8.*/public class DirtyRead {private String username "zjkj";private String password "123";public synchronized void setValue(String username, String password)…

機器學習之提升算法

1、知道提升、梯度提升是什么意思1.1、提升1.2、梯度提升1.3、了解提升算法的過程 2、殘差與殘差平方和(residual sum of squares)3、了解GBDT算法4、了解XGBoost算法5、了解Adaboost算法5.1、Adaboost算法的原理5.2、例子 6、偏差和方差 1、知道提升、梯…

Jsoup遍歷ul li下的鏈接信息實例

2019獨角獸企業重金招聘Python工程師標準>>> Document doc;try {String URL "www.baidu.com";doc Jsoup.connect(URL).get();Elements ElementsUl doc.getElementsByTag("ul");for (Element elementLi : ElementsUl) {Elements provinceEl …

兩篇波蘭地區重金屬污染地區土壤微生物多樣性的研究

環境微生物(包括方興未艾的腸道微生物)在不同的系統中發揮著的生態作用逐漸被意識到,我們對環境微生物實際上仍舊知之甚少,其多樣性問題仍舊是一個非常基礎和重要的課題。這次讀的兩篇文章都是關于波蘭地區重金屬污染地區的土壤微…

jquery中的 $(function(){})

$(function(){})的區別:$(function(){}) 是 $(document).ready(function(){}) 的簡寫,用來在DOM加載完成之后執行一系列預先定義好的函數。 需要注意與(function(){})相比,(function(){})表示一個匿名函數。function(arg){...}定義了一個參數…

機器學習之支持向量機(SVM)總結

文章目錄1、知道SVM相關的各種概念2、知道目標函數、損失函數、正則項的意義2.1、目標函數2.2、損失函數2.3、正則化(添加噪音避免過擬合)3、了解SVM算法原理4、知道SVM的目標函數5、知道SVM的損失函數以及公式6、知道SVM支持向量機的計算過程6.1、推導過…

在CentOS上搭建PHP服務器環境

您也可以使用一鍵自動部署環境的工具,請參見網友開發的這個工具 http://www.centos.bz/2013/08/ezhttp-tutorial/安裝apache:yum install httpd httpd-devel 啟動apache:/etc/init.d/httpd start此時輸入服務器的IP地址,應該看到apache的服務頁面&#x…

jQuery之滾動事件$(window).scroll(function()

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>滾動事件</title><script src"https://code.jquery.com/jquery-2.2.4.min.js"></script><style>img{position:fixe…

《瘋狂Java講義》(二十九)---- JDBC

JDBC編程步驟加載數據庫驅動Class.forName(driverClass). 例如&#xff1a;Class.forName("oracle.jdbc.driver.OracleDriver"); 2. 通過DriverManager獲取數據庫連接。 DriverManager.getConnection(String url, String user, String pwd); 3. 通過Connection對象創…

機器學習之聚類算法的原理推導及相關知識總結

文章目錄1、知道幾個關于"差"的概念2、理解相似度度量的各種方法和相互關系2.1、歐氏距離2.2、jaccard相似系數2.3、余弦相似度2.4、Pearson相似系數2.5、相對熵3、掌握掌握K-Means算法3.1、知道聚類的思想3.2、K-Means算法原理3.3、知道K-Mediods聚類3.4、如何選取K…

Flex 布局教程:語法

Java數組聲明的三種方式 第一種(聲明并初始化)&#xff1a; 數據類型[] 數組名{值,值,...}; 例&#xff1a;int[] a {1,2,3,4,5,6,7,8}; 第二種(聲明后賦值)&#xff1a; 數據類型[] 數組名 new 數據類型[數組長度]; 數組名[下標1]值…

注意:匿名函數調用直接加載函數名setInterval(move,30)

setInterval要求第一個參數必須是含Javascript命令的字符串或函數對象&#xff0c;所以 setInterval("move()",300) 以及 setInterval(move,300) 這兩個都是正確的。 而 setInterval(move(),300) 當Javascript運行到這個語句時&#xff0c;會立即執行move這個函數&am…

vue import組件的使用

vue import組件的使用 1新建/src/component/firstcomponent.vue <template><div id"firstcomponent"><h1>I am a title.</h1></div> </template>2在app.vue引入組件 并且注冊 <script> import firstcomponent from ./comp…

牽絲戲

余少能視鬼&#xff0c;嘗于雪夜野寺逢一提傀儡翁&#xff0c;鶴發襤褸&#xff0c;唯持一木偶制作極精&#xff0c;宛如嬌女&#xff0c;繪珠淚盈睫&#xff0c;惹人見憐。 時云彤雪狂&#xff0c;二人比肩向火&#xff0c;翁自述曰&#xff1a;少時好觀牽絲戲&#xff0c;耽…

機器學習之EM算法的原理推導及相關知識總結

文章目錄1、知道先驗概率和后驗概率2、了解高斯混合模型GMM3、通過最大似然估計推導EM算法的過程的實例4、EM算法5、知道pLSA模型1、知道先驗概率和后驗概率 先驗概率&#xff08;prior probability&#xff09;是指根據以往經驗和分析得到的概率&#xff08;理解為自定義概率…

jQuery中的on 和事件委派

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>事件</title><style>p{width:100px;height:100px;border: 1px solid gray;}</style><script src"https://code.jquery.com/…

python pip處理

查看pip 版本號 pip --version 升級方法 on linux or os X: pip install -U pip on windows: python -m pip install -U pip 轉載于:https://www.cnblogs.com/yangwithtao/p/6397114.html

js中innerHTML和innerText jQuery中html()和text()的區別

js中innerHTML和innerText的區別innerHTML innerHTML 會將標簽和標簽中的內容否獲取回來 innerHTML .innerHTML ‘<p></p>’; 只會將文本內容解析出來&#xff0c;不會顯示標簽innerText innerText 只會將標簽中的內容獲取回來&#xff0c;不會獲取標簽 innerT…