Android 省电开发之 JobSchedule

来源:互联网 发布:淘宝一件代发货源骗局 编辑:程序博客网 时间:2024/05/19 08:26

android的电量一直是所有人关注的问题,

电池越来越大,使用起来没有任何改善,有人觉得是屏幕越来越大导致的,但是实际上更多的是app的不注意,导致的浪费了很多电量。

从本章开始,我们将从开发的角度来告诉大家,如何使我们的应用更加省电的一些技巧。

JobSchedule

这个是Android 5.0之后,考虑到截止我写这篇文章的时候,Android 5.0以上的用户已经增加到25.1%,我觉的在开发中,建议使用JobSchedule来规范我们的开发。

功能:JobSchedule的作用就是将我们需要定时或者特定条件的事件交给系统,当系统满足条件的时候,就会回调我们的组件,运行我们的代码,并且在执行的过程中会回调我们的方法,

条件:在刚刚我说了在特定条件,这个当然不是随便的条件,而是规定好的,(我总结了4+1种条件)

条件1:网络可用

网络可用还可以分为两种
一种是网络可用,任何网络都会触发工作
另一种只有不限制流量的网络触发,这个可以认为是wifi触发

条件2:定时

这个是与其他条件组合使用的,更趋近于deadline的概念,如果在规定时间内,没有任何条件发生,则执行工作

条件3:手机处于空闲状态

设备处于屏幕关闭或dreaming状态(类似window的休眠动画状态)71分钟后,执行工作

条件4:手机是否处于供电稳定状态(充电)

这个也并非只是插入充电器,而且还要在电池处于健康状态的情况下才会触发,一般来说是手机电量>15%

条件+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("");    }}








0 0