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.mzph.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…