Android 省電開發之 JobSchedule
android的電量一直是所有人關注的問題,
電池越來越大,使用起來沒有任何改善,有人覺得是螢幕越來越大導致的,但是實際上更多的是app的不注意,導致的浪費了很多電量。
從本章開始,我們將從開發的角度來告訴大家,如何使我們的應用更加省電的一些技巧。
JobSchedule
這個是Android 5.0之後,考慮到截止我寫這篇文章的時候,Android 5.0以上的使用者已經增加到25.1%,我覺的在開發中,建議使用JobSchedule來規範我們的開發。
功能:JobSchedule的作用就是將我們需要定時或者特定條件的事件交給系統,當系統滿足條件的時候,就會回撥我們的元件,執行我們的程式碼,並且在執行的過程中會回撥我們的方法,
條件:在剛剛我說了在特定條件,這個當然不是隨便的條件,而是規定好的,(我總結了4+1種條件)
條件1:網路可用
網路可用還可以分為兩種 一種是網路可用,任何網路都會觸發工作 另一種只有不限制流量的網路觸發,這個可以認為是wifi觸發條件2:定時
這個是與其他條件組合使用的,更趨近於deadline的概念,如果在規定時間內,沒有任何條件發生,則執行工作條件3:手機處於空閒狀態
裝置處於螢幕關閉或dreaming狀態(類似window的休眠動畫狀態)71分鐘後,執行工作條件4:手機是否處於供電穩定狀態(充電)
這個也並非只是插入充電器,而且還要在電池處於健康狀態的情況下才會觸發,一般來說是手機電量
條件+1:迴圈執行(被列入+1是因為這個需要前四個觸發之後才有用處,當然你也可以把它歸為定時)
這個不是某種條件,但可以設定為迴圈執行方式,即任何條件滿足之後,間隔指定時間仍會執行使用方法:
這裡只是一個使用的最小模型,他並不會有任何的觸發條件,因為我們還沒有新增,(這只是例子啊,你如果真的這麼寫,直接就丟擲異常了,因為不允許不設定任何條件,這樣沒意義)ComponentName mServiceComponent = new ComponentName(this, TestJobService.class); //當事件滿足的時候,呼叫的元件 JobInfo.Builder builder = new JobInfo.Builder(i, mServiceComponent); //i為int值,當前事件的 JobScheduler tm =(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); tm.schedule(builder);
下面依次對每一種觸發進行設定:
網路觸發:
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); //設定為不限制流量的條件觸發,可以認為是wifi條件下觸發
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); //有網路連線的時候觸發
定時:
builder.setOverrideDeadline(time); //其實這裡與我們所想的用法又有所區別,他並沒有單獨提供介面,而是複用,這個方法在後面有另一種用法的介紹。
手機處於空閒狀態:
builder.setRequiresDeviceIdle(true/*false*/); //設定為空閒狀態觸發
手機是否處於供電穩定狀態
builder.setRequiresCharging(true/*false*/); //手機是否處於充電狀態
除了這些條件之外還可以進行一些其他的設定來控制觸發狀態
builder.setMinimumLatency(time); //time的單位是s,作用是滿足觸發條件也要延時time 豪秒之後再觸發
builder.setOverrideDeadline(time); //time的單位是s,作用是設定time豪秒之後,如果沒有任何觸發也執行
builder.setPeriodic(time); //設定迴圈觸發,否則觸發一次就結束了,這樣可以間隔time豪秒之後,還是可以觸發
builder.setPersisted(true/*false*/); //設定觸發條件是否重啟手機後仍有效。 /這個它是通過將presist的資訊,寫到了/data/system/job/jobs.xml檔案中了
builder.setExtras(PersistableBundle extra); //設定startJob時,帶有Bundle
builder.setBackoffCriteria(Long.valueOf(backoffTime) * 1000, backoffPolicy); //這個是比較特殊的,這個是當意外發生的時候,多久之後,重新執行,分為線性計算和指數計算,
綜上就是JobSchedule的基本使用方法,下面我來展示一下Google所給的官方示例:
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler.service;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import com.example.android.jobscheduler.MainActivity;
import java.util.LinkedList;
/**
* Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler
* ultimately land on this service's "onStartJob" method. Currently all this does is post a message
* to the app's main activity to change the state of the UI.
*/
public class TestJobService extends JobService {
private static final String TAG = "SyncService";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service created");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroyed");
}
/**
* When the app's MainActivity is created, it starts this service. This is so that the
* activity and this service can communicate back and forth. See "setUiCalback()"
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Messenger callback = intent.getParcelableExtra("messenger");
Message m = Message.obtain();
m.what = MainActivity.MSG_SERVICE_OBJ;
m.obj = this;
try {
callback.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Error passing service object back to activity.");
}
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
// We don't do any real 'work' in this sample app. All we'll
// do is track which jobs have landed on our service, and
// update the UI accordingly.
jobParamsMap.add(params);
if (mActivity != null) {
mActivity.onReceivedStartJob(params);
}
Log.i(TAG, "on start job: " + params.getJobId());
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
// Stop tracking these job parameters, as we've 'finished' executing.
jobParamsMap.remove(params);
if (mActivity != null) {
mActivity.onReceivedStopJob();
}
Log.i(TAG, "on stop job: " + params.getJobId());
return true;
}
MainActivity mActivity;
private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
public void setUiCallback(MainActivity activity) {
mActivity = activity;
}
/** Send job to the JobScheduler. */
public void scheduleJob(JobInfo t) {
Log.d(TAG, "Scheduling job");
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(t);
}
/**
* Not currently used, but as an exercise you can hook this
* up to a button in the UI to finish a job that has landed
* in onStartJob().
*/
public boolean callJobFinished() {
JobParameters params = jobParamsMap.poll();
if (params == null) {
return false;
} else {
jobFinished(params, false);
return true;
}
}
}
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.jobscheduler.service.TestJobService;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int MSG_UNCOLOUR_START = 0;
public static final int MSG_UNCOLOUR_STOP = 1;
public static final int MSG_SERVICE_OBJ = 2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_main);
Resources res = getResources();
defaultColor = res.getColor(R.color.none_received);
startJobColor = res.getColor(R.color.start_received);
stopJobColor = res.getColor(R.color.stop_received);
// Set up UI.
mShowStartView = (TextView) findViewById(R.id.onstart_textview);
mShowStopView = (TextView) findViewById(R.id.onstop_textview);
mParamsTextView = (TextView) findViewById(R.id.task_params);
mDelayEditText = (EditText) findViewById(R.id.delay_time);
mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
mServiceComponent = new ComponentName(this, TestJobService.class);
// Start service and provide it a way to communicate with us.
Intent startServiceIntent = new Intent(this, TestJobService.class);
startServiceIntent.putExtra("messenger", new Messenger(mHandler));
startService(startServiceIntent);
}
// UI fields.
int defaultColor;
int startJobColor;
int stopJobColor;
private TextView mShowStartView;
private TextView mShowStopView;
private TextView mParamsTextView;
private EditText mDelayEditText;
private EditText mDeadlineEditText;
private RadioButton mWiFiConnectivityRadioButton;
private RadioButton mAnyConnectivityRadioButton;
private CheckBox mRequiresChargingCheckBox;
private CheckBox mRequiresIdleCheckbox;
ComponentName mServiceComponent;
/** Service object to interact scheduled jobs. */
TestJobService mTestService;
private static int kJobId = 0;
Handler mHandler = new Handler(/* default looper */) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UNCOLOUR_START:
mShowStartView.setBackgroundColor(defaultColor);
break;
case MSG_UNCOLOUR_STOP:
mShowStopView.setBackgroundColor(defaultColor);
break;
case MSG_SERVICE_OBJ:
mTestService = (TestJobService) msg.obj;
mTestService.setUiCallback(MainActivity.this);
}
}
};
private boolean ensureTestService() {
if (mTestService == null) {
Toast.makeText(MainActivity.this, "Service null, never got callback?",
Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**
* UI onclick listener to schedule a job. What this job is is defined in
* TestJobService#scheduleJob().
*/
public void scheduleJob(View v) {
if (!ensureTestService()) {
return;
}
JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
String delay = mDelayEditText.getText().toString();
if (delay != null && !TextUtils.isEmpty(delay)) {
builder.setMinimumLatency(Long.valueOf(delay) * 1000);
}
String deadline = mDeadlineEditText.getText().toString();
if (deadline != null && !TextUtils.isEmpty(deadline)) {
builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
}
boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
if (requiresUnmetered) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requiresAnyConnectivity) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
mTestService.scheduleJob(builder.build());
}
public void cancelAllJobs(View v) {
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.cancelAll();
}
/**
* UI onclick listener to call jobFinished() in our service.
*/
public void finishJob(View v) {
if (!ensureTestService()) {
return;
}
mTestService.callJobFinished();
mParamsTextView.setText("");
}
/**
* Receives callback from the service when a job has landed
* on the app. Colours the UI and post a message to
* uncolour it after a second.
*/
public void onReceivedStartJob(JobParameters params) {
mShowStartView.setBackgroundColor(startJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
}
/**
* Receives callback from the service when a job that
* previously landed on the app must stop executing.
* Colours the UI and post a message to uncolour it after a
* second.
*/
public void onReceivedStopJob() {
mShowStopView.setBackgroundColor(stopJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
mParamsTextView.setText("");
}
}
相關推薦
Android 省電開發之 JobSchedule
android的電量一直是所有人關注的問題, 電池越來越大,使用起來沒有任何改善,有人覺得是螢幕越來越大導致的,但是實際上更多的是app的不注意,導致的浪費了很多電量。 從本章開始,我們將從開發的角度來告訴大家,如何使我們的應用更加省電的一些技巧。 JobSchedule
一.Android省電開發之效能優化
電量優化 Android應用開發中的網路、定位、感測器等都是比較耗電的特性,我們應該正確使用API來有效降低應
Android基礎——快速開發之定制BaseTemplate
temp .net fonts The 成了 抽取 一份 應該 我們 初學者肯定會遇到一個日常任務,那麽就是findViewById,setOnClickListener(暫且把它們稱為日常任務),而且很多人會把他們混在一起,導致項目結構混亂,最主要的是寫多了會煩,不覺得嗎
Android基礎——快速開發之打造萬能適配器
臃腫 log 思想 代碼分析 htm 考試報名 做了 順序 基礎 這裏以ListView作演示,對於ListView我們再熟悉不過了,其步驟分為: 創建ListView的Bean對象 創建ListView的Adapter的ItemView布局 創建ListView的Ada
android軟件開發之仿淘寶選擇規格的實現
per con attribute back view.gone boolean 做了 over ear 在一些app開發項目中選擇商品規格這個功能最容易遇到問題,想要實現需要的全部功能,但一直沒有成功,所以就去找了個Demo,學習界面UI采用recyclerview,it
Android USB Host開發之manager.getDeviceList()獲取不到裝置列表【轉載】
原文:https://www.2cto.com/kf/201305/211304.html 同樣遇到這樣的問題,我的Android裝置是原道N12C,官方的4.0.3系統,遇到這個問題,後來找了半天找到的,現在彙總一下吧: 1、建立 android.hardware.usb.h
Android流媒體開發之路一:Camera2採集攝像頭原始資料並手動預覽
Android Camera2採集攝像頭原始資料並手動預覽 最近研究了一下android攝像頭開發相關的技術,也看了Google提供的Camera2Basic呼叫示例,以及網上一部分程式碼,但都是在TextureView等預覽基礎上實現,而我想要做的是在不預覽的情況下,能獲取到攝
Android藍芽開發之低功耗藍芽(藍芽4.0)開發全記錄
主要內容概況 前面我記錄了開發藍芽2.0的過程,今天準備介紹現在的主流藍芽技術,藍芽4.0的開發,該藍芽技術是在Android4.3(API級別18)版本引入的API。 官方文件 具體的區別主要以下幾點: 1.新的藍芽技術提供了連線服務的方法,以前是沒有提供連線藍芽的方法
Android藍芽開發之經典藍芽(藍芽2.0)開發全記錄
前言部分 最近因為需要開始藍芽相關開發,所以在網上搜索了很多內容,並且結合自己的開發過程做了一個總結,先儲備上,也許可能幫到正在做藍芽開發的同學。 藍芽很早就是android裝置上基本通訊功能了,只是以前的沒有那麼多藍芽裝置,現在藍芽裝置種類繁多,所以經常會有人遇到藍芽相關的開發
Android外掛化開發之AMS與應用程式(客戶端ActivityThread、Instrumentation、Activity)通訊模型分析
今天主要分析下ActivityManagerService(服務端) 與應用程式(客戶端)之間的通訊模型,在介紹這個通訊模型的基礎上,再 簡單介紹實現這個模型所需要資料型別。 本文所介紹內容基於android2.2版本。由於Android版本的不同
Android 藍芽開發之搜尋、配對、連線、通訊大全
藍芽( Bluetooth®):是一種無線技術標準,可實現固定裝置、移動裝置和樓宇個人域網之間的短距離資料交換(使用2.4—2.485GHz的ISM波段的UHF無線電波)。藍芽裝置最多可以同時和7個其它藍芽裝置建立連線,進行通訊,當然並不是每一個藍芽都可以達到
Android Unity3D遊戲開發之躲避方塊
開發環境 Window 7 Unity3D 3.4 MB525 defy Android 2.1-update1 羽化的第四篇部落格,這次給大家送上自己初學Unity時寫的一個小遊戲Demo,我叫它“躲避方塊”,其實這個遊戲可以無限擴充套件,可以做成聯機
Android下jni開發之ndk的使用(下載、配置、編譯遇到的問題)
Android下jni開發之ndk的使用 一、簡介 JNI和NDK很多Android開發初學者沒有搞明白這個問題,JNI是Java呼叫Native機制,是Java語言自己的特性全稱為Java Native Interface,類似的還
android ReactNative混合開發之最新教程
參考官方文件->react native 文件 本文使用開發環境 Android studio 注意最新的react native支援的最新的SDK為16(android4.1) 建立Android專案(已有專案跳過) 開啟Android studio 輸入專案名稱,選擇專案目錄,點選nex
ArcGIS Android API 應用開發之圖形繪製與長度面積量算
本文通過一個簡單的小Demo,向大家介紹如何使用ArcGIS Android API繪製點、線、面圖形,並且測量線的長度和多邊形的面積。 首先來看一下程式執行的效果圖: 實現上述功能,首先需要向地圖中新增一個GraphicsLayer,用來繪製Point、Poly
Android省電策略及測試
1、電源測試----------------------------------------------------1)檢視電源狀態:adb shell dumpsys batteryCurrent Battery Service state: (UPDATES STOPP
android+unity3D遊戲開發之音效播放
音效讓我們的遊戲更逼真,更有情調,呵呵,今天我們來播放一首賽車加速的音效吧。 首先先把我們的賽車音效加入到工程裡面(這個會吧,直接拖進去就行了); 然後就是新建一個javascript文字,指令碼程式碼如下: var oldboy:Audio
【Android】Adroid開發之判斷一個自己的apk是否已經簽名
今天給大家帶來一個知識點,那就是判斷自己的android應用apk是否進行了簽名。我這裡是用的Windows 測試。首先,進入我們的jdk的安裝目錄。如這裡是我的:D:\Users\kaifagongju\Java\jdk1.7.0_79\bin 然後,
Android控制元件開發之Gallery3D酷炫效果 瀏覽圖片
效果網上已經很多人做出來了,只是這次需要用到,所以自己也實踐了一下(這裡例子我也是根據網上一些資料編寫)。特下面針對一些關鍵程式碼進行簡要說明,需要做這方面東西的朋友可以看看。這篇文章是實用性文章,理論分析不多。
Android樣式的開發之drawable
0 概述 res/drawable目錄下是Android用來存放圖片資原始檔的路徑。這裡除了有常規的圖片外,還支援selector/shape等定製或自定義圖片。 資源命名規則 下面將詳細分析: 1.1 StateListDrawable