電量優(yōu)化

1.為了省電函卒,有些工作可以當手機插上電源的時候去處理。

像這些不需要及時地和用戶交互的操作可以放到后面處理虱咧。
比如:360手機助手锚国,當充上電的時候,才去更新App

如何立即獲取手機當前充電狀態(tài)?

//獲取手機充電狀態(tài)

public boolean isPlugged() {
        // 通過廣播接收者獲取
        IntentFilter intentFilter = new IntentFilter(
                Intent.ACTION_BATTERY_CHANGED);

        // 獲取Intent绘沉。充電情況在intent中
        Intent intent = this.registerReceiver(null, intentFilter);
        // 獲取充電狀態(tài)。int值车伞。int可以代表很多狀態(tài)。
        int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

        // USB充電
        boolean usb = pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
        // 交流點充電
        boolean ac = pluggedState == BatteryManager.BATTERY_PLUGGED_AC;
        // 無線充電,當無線充電支持api >= 17
        boolean wireless = false;
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wireless = pluggedState == BatteryManager.BATTERY_PLUGGED_WIRELESS;
        }
        return usb || ac || wireless;
    }

2.Wake Lock

在使用該類的時候困曙,必須保證acquire和release是成對出現的慷丽。

因為創(chuàng)建和持有喚醒鎖對電池的續(xù)航有較大的影響鳄哭。如果不釋放WakeLock的話,CPU一直運行杨耙,耗電會非称矗快容握。

3.集中處理算法,JobSchedule/GCM

CUP喚醒時的高峰線:

image.png

從上圖可以看出塑猖。在喚醒的CPU耗電是相對于喚醒之后要高得多得多羊苟。

所以大量高頻次的CPU喚醒及操作感憾,我們最好把這些喚醒和操作集中處理。這樣有利于優(yōu)化電量
我們可以采取一些算法來解決凉倚。
谷歌提供了Jobschedule(5.0Api)/GCM算法來解決。

JobScheduler示例:

JobService

package com.zsj.jobscheduler;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.annotation.SuppressLint;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;

@SuppressLint("NewApi")
public class MyJobScheduler extends JobService {
    private static final String LOG_TAG = "zsjJobScheduler";

    @Override
    public boolean onStartJob(JobParameters params) {
        // 這是您實現所有工作邏輯的地方稽寒。 請注意杏糙,這運行
        // 在主線程上,所以您將要使用單獨的線程進行異步工作
        // false: 該系統(tǒng)假設任何任務運行不需要很長時間并且到方法返回時已經完成宏侍。
        // true: 該系統(tǒng)假設任務是需要一些時間并且當任務完成時需要調用jobFinished()告知系統(tǒng)。

        // 首先漫蛔,檢查網絡旧蛾,然后嘗試連接。
        if (isNetworkConnected()) {
            new SimpleDownloadTask().execute(params);
            return true;
        } else {
            Log.i(LOG_TAG, "沒有網絡去工作" + params.getJobId());
        }
        return false;
    }

    /**
     * 確定設備當前是否在線毯盈。
     */
    private boolean isNetworkConnected() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        // 如果在調用jobFinished()之前必須停止作業(yè)搂赋,則這個方法益缠。
        return false;
    }

    /**
     * 異步任務
     */
    private class SimpleDownloadTask extends
            AsyncTask<JobParameters, Void, String> {

        protected JobParameters mJobParam;

        @Override
        protected String doInBackground(JobParameters... params) {
            mJobParam = params[0];
            try {
            //做耗時操作
            } catch (IOException e) {
                return "下載失敗";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            // job 完成幅慌。
            jobFinished(mJobParam, false);
            Log.i(LOG_TAG, "獲取結果 : " + result);
        }
    }

}

調用:

package com.zsj.jobscheduler;

import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

    private ComponentName mJobService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startService(new Intent(this, MyJobScheduler.class));
        mJobService = new ComponentName(this, MyJobScheduler.class);

    }

    public void jobschedule(View view) {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        for (int i = 0; i < 50; i++) {
            int jobId = i;
            /*
             * new JobInfo.Builder(jobId, mJobService)
             * 第一個參數為該任務的標識符 
             * 第二個參數是你希望用來處理該任務的服務對應的ComponentName胰伍,用來啟動該服務
             */
            JobInfo job = new JobInfo.Builder(jobId, mJobService)
            /*
             * setBackoffCriteria(initialBackoffMillis, backoffPolicy)//
             * 設置退避/重試策略。當一個任務的調度失敗時需要重試祷杈,所采取的策略渗饮。
             * 第一個參數時第一次嘗試重試的等待間隔,單位為毫秒特占。預設的參數有:DEFAULT_INITIAL_BACKOFF_MILLIS.,MAX_BACKOFF_DELAY_MILLIS 
             * 第二個參數是對應的退避策略云茸,預設的參數有:BACKOFF_POLICY_EXPONENTIAL——指數增長退避策略。BACKOFF_POLICY_LINEAR-線性策略
             */
            .setBackoffCriteria(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
            .setMinimumLatency(60)//設置任務執(zhí)行延遲的時長
//          .setPeriodic(long interval)//設置周期懊纳。可以保證在每個間隔之間任務最多只執(zhí)行一次  
//          .setPeriodic (long interval, long flexMillis) //在周期末的一個flex長度的窗口期()嗤疯,任務都有可能被執(zhí)行
//          .setPersisted (boolean isPersisted) 設置當設備重啟后,這個任務是否還保留戏罢。需要RECEIVE_BOOT_COMPLETED權限
            /*
             * setRequiredNetworkType (int networkType) 設置要求的網絡脚囊,只有連接給定類型的網絡才能執(zhí)行,常用預設值有:
             * NETWORK_TYPE_UNMETERED - 免費網絡, NETWORK_TYPE_ANY - 任意網絡
             */
//          .setRequiresCharging (boolean requiresCharging) 設置是否需要充電CIA執(zhí)行。默認false
//          setRequiresDeviceIdle (boolean requiresDeviceIdle) 設置是否需要設備處于空閑時執(zhí)行讲岁。默認false
            .build();//創(chuàng)建對應的JobInfo
            jobScheduler.schedule(job);
        }
    }
}

注冊:

   <service
            android:name="com.zsj.jobscheduler.MyJobScheduler"
            android:permission="android.permission.BIND_JOB_SERVICE" >
        </service>

也可參考谷歌官方Demo:https://github.com/googlesamples/android-JobScheduler

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末缓艳,一起剝皮案震驚了整個濱河市看峻,隨后出現的幾起案子,更是在濱河造成了極大的恐慌舶治,老刑警劉巖车猬,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尺锚,死亡現場離奇詭異,居然都是意外死亡伏嗜,警方通過查閱死者的電腦和手機伐厌,發(fā)現死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門挣轨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人卷扮,你說我怎么就攤上這事均践⊥” “怎么了或衡?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長偷办。 經常有香客問我澄港,道長,這世上最難降的妖魔是什么废岂? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任狱意,我火速辦了婚禮,結果婚禮上财骨,老公的妹妹穿的比我還像新娘藏姐。我一直安慰自己,他們只是感情好羔杨,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布兜材。 她就那樣靜靜地躺著,像睡著了一般曙寡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上执隧,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音捅膘,去河邊找鬼。 笑死寻仗,一個胖子當著我的面吹牛凡壤,可吹牛的內容都是我干的。 我是一名探鬼主播亚侠,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箕别!你這毒婦竟也來了滞谢?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤母截,失蹤者是張志新(化名)和其女友劉穎橄教,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體护蝶,經...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡滓走,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绽族。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涛漂,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情瓢剿,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布间狂,位于F島的核電站鉴象,受9級特大地震影響,放射性物質發(fā)生泄漏何鸡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一淆游、第九天 我趴在偏房一處隱蔽的房頂上張望稽犁。 院中可真熱鬧,春花似錦已亥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泥技,卻和暖如春磕仅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榕订。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贩幻,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓丛楚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仿荆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容