android学习(二十一) 下载数据减少电池损耗

高效的网络访问(优化下载)

使用无线网络下载数据是你的应用消耗电池潜在的重要原因之一。为了降低和网络有关的activity连接导致的电池消耗。你理解你的连接模型怎样影响无线硬件这是很关键的。

下面将介绍无线硬件和解释你的应用的连接模型和它是如何互动的。以及为了降低你的数据连接提供一些建议性的方式:使用预读取,捆绑你的传输为了降低电池的损耗。


无线硬件

一个十分活跃的无线硬件消耗的功率是显著的。所以当不在使用的时候为了降低功率他会在不同的能量状态之间转换。设备”供电”,尝试降低延迟当它需要的时候。

典型的3G网络无线状态硬件有3个能量状态。
1. 全功率:当一个连接激活使用时,允许设备在最高速率下传输数据。
2. 低功率:一种在满状态下使用约50%的电池电量的中间状态。
3. 待机:最小的能量状态,在此期间没有网络连接是激活的或需要的。

尽管低和待机状态电池消耗很小,但他们也带了网络请求延迟。从低状态返回全功率需要大约1.5s,当从待机到全功率需要大约2s。

为了尽量减少等待时间,状态机采用了延迟推迟到低能态的转变。图一使用 AT&T的计时对于一个典型的3g无线Typical 3G wireless radio state machine

在每个设备的无线硬件,尤其是有关转换的延迟和开机延迟,根据不用的无线技术的使用 (2G, 3G, LTE, etc.)是不同的。和由设备运行的载波网络定义和配置。

描述典型代表3G无线,是基于data provided by AT&T,然而为了全部的无线的实现,一般的基本原则和最好的实践结果是应用。

这个方法是特别有效的对网页浏览器,当用户浏览网络的时候他会避免不需要的延迟。

不幸的是,不幸的是,这种方法可能会导致在现代智能手机OSS像Android里的效率低下的应用程序,其中的应用程序运行在前台(其中的延迟是很重要的)和背景(其中电池寿命应优先)。


应用程序如何影响无线硬件

每次你创建新的网络连接时,无线就会转换到全功率状态。在3G运行的情况下,他将在全功率保持为了持续传输–增加一个额外的5s尾时间接下来的12s在低能量状态。所以一个3G设备,每次数据传输都将消耗能量大约20s。

在实际运用中,这意味着一个应用,每18s,传输非捆绑数据1s将使无线硬件一直保持激活状态,正如它刚要进入待机模式就会转移回高功率。因此,每分钟它在高功率状态将消耗电池18s,在低功率状态还要42s。

通过比较,相同的应用每分钟3s传输捆绑数据,高功率仅保持8s,低功率仅增加12s。

第二个例子允许无线硬件待机每分钟40秒,从而导致电池消耗的大量减少。
图二:捆绑与非捆绑转让相关无线射频功率使用
 Relative wireless radio power use for bundled versus unbundled transfers


预取数据

预取数据是减少独立数据传输数量的有效方法。预取允许你下载你可能需要的全部数据作为一个待定的选择。

通过在前面加载你的传输,你会减少无线下载数据的请求数量。因此,您不仅节省电池寿命,而且还改善了延迟,降低所需的带宽,并减少下载次数。

预读通过最大限度地减少在等待下载之前进行的行动或观看数据所造成的应用程序延迟。

然而,太过积极的使用,预读带来了增加电池消耗的风险和带宽使用(像流量限制,下载无用的数据)。确保当等待预读完成使,预读不会延迟应用的启动也是很重要的。在实际应用中,可能意味着逐步处理数据,或启动连续传输优先级,以便应用程序启动所需的数据首先下载和处理。

如何积极的预取取决于正在下载的数据的大小和它被使用的可能性。基于上面描述的状态机,有50%的可能性是在当前用户会话使用的数据,通常预取6秒左右(约1-2 MB)。

一般来说,这是很好的做法,预取数据,你只需要启动另一个下载每2至5分钟约1至5兆字节。

按照这个原则,大量的下载,如视频文件,应定期下载块(每2至5分钟),实际上就是预取在下面几分钟可能会被看到的数据。

请注意,进一步下载应该捆绑,如在下一节中,批处理传输和连接,这些近似将根据不同的连接类型和速度,如讨论根据连接类型修改下载模式。

让我们看看一些实际的例子:

一个音乐播放器

您可以选择预取整个专辑,但如果用户在第一首歌后就停止听了,你就已经浪费了大量的带宽和电池寿命。

一个更好的方法是保持一首歌曲的缓冲区,除了正在播放的音乐。对于流媒体音乐,而不是保持一个连续的流,保持电台在任何时候都活跃,考虑使用HTTP现场流来传输音频流突发,模拟预取方法如上所述。

一个新闻阅读器

许多新闻应用尝试减少带宽通过只下载标题,当一个类别被选择后,当用户想要阅读时仅显示整体文章,正如滑动视图只显示略缩图。

使用这种方法,无线将被迫保持活跃对于大多数用户的新闻阅读会话,因为他们滚动标题,改变类别,并阅读文章。不仅如此,当切换类别或阅读文章时,能量状态之间的恒定切换会导致显著的延迟。

一个更好的方法是将要开始启动时预取合理的数据量,开始第一个设置,新闻标题和缩略图保证低延迟启动时间和继续处理剩余的标题和缩略图,每篇文章的文章正文至少可以从主要标题列表中获得。

另一种方法是每一个预取标题,缩略图,文章的文字,甚至可能是整篇文章的图片,一般在预定的时间表的背景。这种方法的风险支出显著的带宽和电池寿命下载该从来没有使用的内容,所以应谨慎实施。

一种解决方案是,只有当连接到Wi-Fi时,才可能发生完整的下载,并且可能只有当设备处于充电状态时。


批传输和连接

每次你启动一个连接,在不顾数据传输的大小时,当时用3G有都有可能造成20s的能量消耗。

一个应用每20s向服务器发出信号,只是为了确认应用程序运行和可见的用户,将保持无线无限期供电,造成了显着的电池成本为了几乎没有实际应用的数据传输。

考虑到这一点,捆绑您的数据传输,并创建一个待定的传输队列是非常重要的。做得正确,由于发生在类似的时间窗口你可以有效地传输,使他们所有同时发生,确保无线尽可能减少能量消耗。

这种方法的基本理念是在每个传输会话尽可能多的数据传输,你需要努力限制会话的数量。

这意味着,你需要批次传输通过队列延迟大的传输,优先计划更新和预取。因此,他们都执行时,时间敏感的传输是必需的。同样,您的计划更新和定期预取应该启动您的挂起传输队列的执行。

使用上述预取例程的新闻应用程序。新闻阅读器收集分析信息,了解其用户的阅读模式和排名最受欢迎的故事。为了保持新闻新鲜,它每小时检查更新。为了节省带宽,而不是下载完整的照片好和每一篇文章,它的预取只有缩略图和被选中时下载完整的照片。

在这个例子中,所有的分析信息收集在应用程序应该捆绑在一起排队等待下载,而不是被发送,因为它的收集。当一个完整大小的照片被下载,或当每小时更新正在执行时,将所得的捆绑数据传输。

任何时间敏感的或按需传输如下载一个全尺寸的图像应该比定期更新优先。计划更新应该在按需传输的同时执行,下一次更新将在设置间隔之后发生。这种方法减轻了定期更新的必要时间敏感的照片下载的定期备份的成本。


减少连接

重用现有的网络连接通常比启动新的网络连接更有效。重用连接还允许网络更智能地应对拥塞和相关的网络数据问题。

而不是创建多个同时连接下载数据,或连接多个连续的GET请求,在可能的情况下,你应该捆绑这些请求到一个单一的GET。

例如,在单个请求/响应中对单个新闻文章进行单一请求,比对多个新闻类别进行多个查询更有效。无线需要变得活跃为了传递解除/终止确认数据包服务器和客户端关联,所以它也具有很好的实践,关闭你的连接,当他们不在使用,而不是等待这些超时。

也就是说,过早关闭一个连接可以防止它被重复使用,这就需要额外的开销来建立一个新的连接。一个有用的折衷方法不是立即关闭连接,而是在固有超时过期之前关闭它


使用DDMS网络流量工具来确定关注区域

android DDMS (Dalvik Debug Monitor Server)
包含了一个包括详细的网络使用标签,当你的应用正在使用网络请求时他能做到追踪。使用这个工具,您可以监视应用程序如何以及何时传输数据并适当优化底层代码。
图3:显示了一个小数据量大约相隔15秒,这表明通过预取每个请求或捆绑上传可以大大提高效率。

这里写图片描述

通过监测您的数据传输的频率,以及在每个连接期间传输的数据量,您可以识别您的应用程序的使用更多的电池功率的区域。一般来说,你会寻找可以延迟的短针状,或应引起被后来抢占的转移。

为了更好地确定转移尖峰的原因,流量状态API允许让你的标签数据传输发生在一个线程使用TrafficStats.setThreadStatsTag()方法。其次是手动标注和未标注的单个sockets使用TrafficStats.tagSocket()TrafficStats.untagSocket()。例如:

TrafficStats.setThreadStatsTag(0xF00D);
TrafficStats.tagSocket(outputSocket);
//传输数据使用socket
TrafficStats.untagSocket(outputSocket);

HttpURLConnection库自动标记sockets根据当前* TrafficStats.getThreadStatsTag()*的值。这个库也标记和不标记sockets当垃圾回收处理。

private class IdentifyTransferSpikeTask extends AsyncTask {
    @Override
    protected void onPreExecute() {
      TrafficStats.setThreadStatsTag(0xF00D);
    }

    @Override
    protected String doInBackground(String... urls) {
        try {
            //使用网络请求HttpURLConnection.connect()
        }
    }

    @Override
    protected void onPostExecute(String result) {
        TrafficStats.clearThreadStatsTag();
   }
}

socket标记在android4.0被支持,但实时数据只会显示在运行Android 4.0.3或更高的设备。


最小化定期更新的影响

最优的定期更新是根据设备状态,网络连接,使用者的习惯和清楚使用者的偏爱。

优化电池寿命讨论如何建立电池效率高的应用程序,修改其刷新频率的基础上是主机设备的状态。这包括禁用后台服务更新,当您失去连接,并降低更新率时。当电池电量低时。


使用Firebase Cloud Messaging作为替代轮询

每次您的应用程序轮询您的服务器检查是否需要更新,在3G连接需要20s的不必要的能量消耗。

Firebase Cloud Messaging (FCM)用于将数据从服务器传输到特定应用程序实例的轻量级机制。使用FCM,,有新的数据时您的服务器可以通知您的应用程序运行在一个特定的设备。

与轮询相比,在您的应用程序必须定期请求服务器查询新的数据,这个事件驱动的模型只有当它知道有数据下载允许您的应用程序创建一个新的连接。该模型最大限度地减少不必要的连接,减少延迟时,更新您的应用程序中的信息。

FCM实现使用持久的TCP / IP连接。虽然有可能实现自己的推送服务,最好使用FCM。这最大限度地减少持久连接的数量,并允许该平台优化带宽,并尽量减少对电池寿命的相关影响。


网络计划工具

如果您的应用程序需要轮询,Android平台提供了多种工具来帮助您创建一个高效的时间表,完成网络任务,如轮询。这些工具包括JobScheduler、AlarmManager,和Firebase JobDispatcher。要了解更多关于使用这些工具,请参见Intelligent Job-Scheduling


重复下载是多余的

许多你的应用程序的用户有间歇性访问互联网或有限制的信息量,他们可以下载到他们的设备。

您可以鼓励用户与您的应用程序进行交互,通过减少您的应用程序需要下载的数据量。

减少下载量最基本的方法就是只下载你需要的东西。在数据方面,这意味着实现REST API,它允许您指定查询参数,通过使用上次更新的时间等参数来限制返回的数据。

类似地,在下载图像时,减少服务器端图像的大小,而不是下载在客户端上缩小的全尺寸图像是很好的做法。


本地缓存文件

另一个重要的技术是避免下载重复数据。使用缓存可以减少重复下载相同数据的可能性。通过缓存你的应用程序的数据和资源,你创建一个本地副本的信息,你的应用程序需要参考。如果您的应用程序需要在短时间内多次访问相同的信息,您只需要下载缓存一次。

重要的是尽可能地缓存,以减少您下载的数据总量。总是缓存静态资源,包括按需下载,如全尺寸图像,只要合理。按需资源应分别存储,使您能够定期刷新按需缓存,以管理其大小。

为了确保您的缓存不会导致您的应用程序显示不新鲜的数据,请务必从HTTP响应头中提取被请求的内容上次更新的时间,以及何时过期。这将允许您确定相关内容何时应刷新。

//URL表示包含要放入缓存的内容的网站。
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

long currentTime = System.currentTimeMillis();
long expires = conn.getHeaderFieldDate("Expires", currentTime);
long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

// lastUpdateTime代表缓存最后更新。
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified;
}

使用这种方法,您还可以有效地缓存动态内容,同时确保它不会导致您的应用程序显示过时的信息。

可以在非托管外部缓存目录中缓存非敏感数据:

Context.getExternalCacheDir();

或者,您可以使用托管的、安全的应用程序缓存。注意,当系统在可用存储器上运行不足时,可能会刷新内部缓存。

Context.getCacheDir();

注:当应用被卸载时缓存应要删除


使用HttpsURLConnection响应缓存

Android 4.0添加了一个响应缓存的httpsurlconnection。你可以启用HTTP响应缓存在支持的设备上使用反射如下:

private void enableHttpResponseCache() {
  try {
    long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
    File httpCacheDir = new File(getCacheDir(), "http");
    Class.forName("android.net.http.HttpResponseCache")
         .getMethod("install", File.class, long.class)
         .invoke(null, httpCacheDir, httpCacheSize);
  } catch (Exception httpResponseCacheNotAvailable) {
    Log.d(TAG, "HTTP未获得缓存");
  }
}

此示例代码将打开安卓4.0 +设备上的响应缓存,而不会影响早期版本。

随着缓存的安装,完全缓存的HTTP请求可以直接从本地存储,不需要打开网络连接。有条件缓存响应可以从服务器验证其新鲜性,消除与下载相关的带宽成本。


根据连接类型修改下载模式

当涉及到电池寿命的影响时,并非所有的连接类型都是平等的。Wi-Fi无线电不仅比无线数据使用更少的电池,而且在不同的无线无线电技术中使用的无线电有不同的电池影响


使用WIFI

在大多数情况下,Wi-Fi无线电将提供更大的带宽,显着较低的电池成本。因此,您应该连接Wi-Fi时尽可能进行数据传输。

你可以使用广播接收机听连接变化表明当一个Wi-Fi连接已建立执行重要的下载,优先计划的更新,甚至可以暂时增加定期更新频率为优化电池寿命,确定和监控连接状态。


使用更大的带宽来下载更少的数据

当连接在无线硬件,更高的带宽通常以较高的电池成本的代价。这意味着LTE通常消耗更多的能量比3G,这反过来2G又更昂贵。

您可以使用连接管理器来确定活动的无线硬件,并据此修改预取程序

ConnectivityManager cm =
 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

TelephonyManager tm =
  (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

int PrefetchCacheSize = DEFAULT_PREFETCH_CACHE;

switch (activeNetwork.getType()) {
  case (ConnectivityManager.TYPE_WIFI):
    PrefetchCacheSize = MAX_PREFETCH_CACHE; break;
  case (ConnectivityManager.TYPE_MOBILE): {
    switch (tm.getNetworkType()) {
      case (TelephonyManager.NETWORK_TYPE_LTE |
            TelephonyManager.NETWORK_TYPE_HSPAP):
        PrefetchCacheSize *= 4;
        break;
      case (TelephonyManager.NETWORK_TYPE_EDGE |
            TelephonyManager.NETWORK_TYPE_GPRS):
        PrefetchCacheSize /= 2;
        break;
      default: break;
    }
    break;
  }
  default: break;
}

摘自android developer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值