安卓电量优化之JobScheduler使用介绍

一、JobScheduler概述

JobScheduler是安卓5.0版本推出的API,允许开发者在符合某些条件时创建执行在后台的任务。在Android开发中,会存在这些场景:你需要在稍后的某个时间点或者当满足某个特定的条件时执行一个任务,例如当设备接通电源适配器或者连接到WIFI,此时就可以使用JobScheduler了,当一系列预置的条件被满足时,JobScheduler API为你的应用执行一个操作。与AlarmManager不同的是这个执行时间是不确定的。除此之外,JobScheduler API允许同时执行多个任务。

JobSchedule的宗旨就是把一些不是特别紧急的任务放到更合适的时机批量处理。这样做有两个好处:避免频繁的唤醒硬件模块,造成不必要的电量消耗以及避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量。

JobSchedule适用版本为5.0及以上,目前还未发现兼容库支持。

二、JobScheduler使用

使用JobScheduler首先我们需要创建一个类继承自JobService且必须实现两个方法(JobService继承自Service),分别是onStartJob(JobParameters params)onStopJob(JobParameters params),如下:

 1 public class TestJobService extends JobService {
 2
 3     @Override
 4     public boolean onStartJob(JobParameters params) {
 5
 6         return false;
 7     }
 8
 9     @Override
10     public boolean onStopJob(JobParameters params) {
11
12         return false;
13     }
14 }

当任务开始时会执行onStartJob(JobParameters params)方法,这是系统用来触发已经被执行的任务。这个方法返回一个boolean值。

如果返回值是false,系统假设这个方法返回时任务已经执行完毕。

如果返回值是true,那么系统假定这个任务正要被执行,执行任务的重担就落在了开发者的肩上,当任务执行完毕时开发者需要自己调用jobFinished(JobParameters params, boolean needsRescheduled)来通知系统。

当系统接收到一个取消请求时,会调用onStopJob(JobParameters params)方法取消正在等待执行的任务。很重要的一点是如果onStartJob(JobParameters params)返回false,那么系统假定在接收到一个取消请求时已经没有正在运行的任务。onStopJob(JobParameters params)在这种情况下不会被调用。

需要注意的是这个job service运行在你的主线程,这意味着你需要使用子线程,handler, 或者一个异步任务来运行耗时的操作以防止阻塞主线程。我们可以在onStartJob中利用Handler发送消息,在Handler中处理相关任务。

jobFinished(JobParameters params, boolean needsRescheduled)的两个参数中的params参数是从JobService的onStartJob(JobParameters params)的params传递过来的,needsRescheduled参数是告诉系统这个任务如果由于某些原因导致执行失败是否需要重新调度执行,true需要重新调度执行,false不需要。

最后我们需要到AndroidManifest.xml中添加一个service节点让你的应用拥有绑定和使用这个JobService的权限。

1 <service
2    android:name=".TestJobService"
3    android:permission="android.permission.BIND_JOB_SERVICE" >
4 </service>

在创建完TestJobService后,我们就该创建JobScheduler对象了,创建JobScheduler对象需要通过getSystemService( Context.JOB_SCHEDULER_SERVICE )来初始化:

1 JobScheduler tm =(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);

接下来我们使用JobInfo.Builder来构建一个JobInfo对象。JobInfo.Builder接收两个参数,第一个参数是你要运行的任务的标识符,简单理解为这个任务的ID就可以了,第二个是这个Service组件的类名。

1 JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);

mServiceComponent初始化如下:

1 mServiceComponent = new ComponentName(this, TestJobService.class);

builder允许你设置很多不同的选项来控制任务的执行,重要方法说明如下:

方法名 说明
setPeriodic(long intervalMillis) 设置任务每隔intervalMillis运行一次
setMinimumLatency(long minLatencyMillis) 这个函数能让你设置任务的延迟执行时间(单位是毫秒),这个函数与setPeriodic(long time)方法不兼容,如果这两个方法同时调用了就会引起异常
setOverrideDeadline(long maxExecutionDelayMillis) 这个方法让你可以设置任务最晚的延迟时间。如果到了规定的时间时其他条件还未满足,你的任务也会被启动。与setMinimumLatency(long time)一样,这个方法也会与setPeriodic(long time),同时调用这两个方法会引发异常
setPersisted(boolean isPersisted) 这个方法告诉系统当你的设备重启之后你的任务是否还要继续执行
setRequiredNetworkType(int networkType) 这个方法让你这个任务只有在满足指定的网络条件时才会被执行。默认条件是JobInfo.NETWORK_TYPE_NONE,这意味着不管是否有网络这个任务都会被执行。另外两个可选类型,一种是JobInfo.NETWORK_TYPE_ANY,它表明需要任意一种网络才使得任务可以执行。另一种是JobInfo.NETWORK_TYPE_UNMETERED,它表示设备不是蜂窝网络( 比如在WIFI连接时 )时任务才会被执行
setRequiresCharging(boolean requiresCharging) 这个方法告诉你的应用,只有当设备在充电时这个任务才会被执行
setRequiresDeviceIdle(boolean requiresDeviceIdle) 这个方法告诉你的任务只有当用户没有在使用该设备且有一段时间没有使用时才会启动该任务

需要注意的是setRequiredNetworkType(int networkType), setRequiresCharging(boolean requireCharging) and setRequiresDeviceIdle(boolean requireIdle)者几个方法可能会使得你的任务无法执行,除非调用setOverrideDeadline(long time)设置了最大延迟时间,使得你的任务在未满足条件的情况下也会被执行。一旦你预置的条件被设置,你就可以构建一个JobInfo对象,然后通过如下所示的代码将它发送到你的JobScheduler中

1 if( tm.schedule( builder.build() ) <= 0 ) {
2     //something wrong
3 }

schedule方法会返回一个整型。如果schedule方法失败了,它会返回一个小于0的错误码。否则返回我们在JobInfo.Builder中定义的标识id。

停止某个任务,可以调用JobScheduler对象的cancel(int jobId)来实现;如果想取消所有的任务,可以调用JobScheduler对象的cancelAll()来实现。

以上就是JobScheduler的介绍,是不是很简单,重要的是理解什么情况下使用JobScheduler。

三、JobScheduler实例举例

本Demo是安卓官方提供的一个例子,我们先看TestJobService类;

 1 public class TestJobService extends JobService {
 2     private static final String TAG = "SyncService";
 3
 4     @Override
 5     public void onCreate() {
 6         super.onCreate();
 7         Log.i(TAG, "Service created");
 8     }
 9
10     @Override
11     public void onDestroy() {
12         super.onDestroy();
13         Log.i(TAG, "Service destroyed");
14     }
15
16
17     @Override
18     public int onStartCommand(Intent intent, int flags, int startId) {
19         Messenger callback = intent.getParcelableExtra("messenger");
20         Message m = Message.obtain();
21         m.what = MainActivity.MSG_SERVICE_OBJ;
22         m.obj = this;
23         try {
24             callback.send(m);
25         } catch (RemoteException e) {
26             Log.e(TAG, "Error passing service object back to activity.");
27         }
28         return START_NOT_STICKY;
29     }
30
31     @Override
32     public boolean onStartJob(JobParameters params) {
33         // We don‘t do any real ‘work‘ in this sample app. All we‘ll
34         // do is track which jobs have landed on our service, and
35         // update the UI accordingly.
36        jobParamsMap.add(params);
37         if (mActivity != null) {
38             mActivity.onReceivedStartJob(params);
39         }
40         Log.i(TAG, "on start job: " + params.getJobId());
41         return true;
42     }
43
44     @Override
45     public boolean onStopJob(JobParameters params) {
46         // Stop tracking these job parameters, as we‘ve ‘finished‘ executing.
47         jobParamsMap.remove(params);
48         if (mActivity != null) {
49             mActivity.onReceivedStopJob();
50         }
51         Log.i(TAG, "on stop job: " + params.getJobId());
52         return true;
53     }
54
55    MainActivity mActivity;
56     private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
57
58     public void setUiCallback(MainActivity activity) {
59         mActivity = activity;
60     }
61
62     /** Send job to the JobScheduler. */
63     public void scheduleJob(JobInfo t) {
64         Log.d(TAG, "Scheduling job");
65         JobScheduler tm =
66                 (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
67         if(tm.schedule(t)<=0){
68             Log.i(TAG, "something wrong");
69         }
70     }
71
72
73     /**
74      * Not currently used, but as an exercise you can hook this
75      * up to a button in the UI to finish a job that has landed
76      * in onStartJob().
77      */
78     public boolean callJobFinished() {
79         JobParameters params = jobParamsMap.poll();
80         if (params == null) {
81             return false;
82         } else {
83             jobFinished(params, false);
84             return true;
85         }
86     }
87 }

上面提到过JobService其实也是Service,同样具有相应生命周期方法。TestJobService先不做详细讲解,但是要看到这个类中封装了一些JobScheduler方法供外界调用。

接下来我们结合MainActivity类一起看,MainActivity源码如下:

  1 public class MainActivity extends Activity {
  2
  3     private static final String TAG = "MainActivity";
  4
  5     public static final int MSG_UNCOLOUR_START = 0;
  6     public static final int MSG_UNCOLOUR_STOP = 1;
  7     public static final int MSG_SERVICE_OBJ = 2;
  8     // UI fields.
  9     int defaultColor;
 10     int startJobColor;
 11     int stopJobColor;
 12
 13     private TextView mShowStartView;
 14     private TextView mShowStopView;
 15     private TextView mParamsTextView;
 16     private EditText mDelayEditText;
 17     private EditText mDeadlineEditText;
 18     private RadioButton mWiFiConnectivityRadioButton;
 19     private RadioButton mAnyConnectivityRadioButton;
 20     private CheckBox mRequiresChargingCheckBox;
 21     private CheckBox mRequiresIdleCheckbox;
 22     ComponentName mServiceComponent;
 23     TestJobService mTestService;
 24     //
 25     private static int kJobId = 0;
 26
 27     @Override
 28     public void onCreate(Bundle savedInstanceState) {
 29         super.onCreate(savedInstanceState);
 30         setContentView(R.layout.sample_main);
 31         Resources res = getResources();
 32         defaultColor = res.getColor(R.color.none_received);
 33         startJobColor = res.getColor(R.color.start_received);
 34         stopJobColor = res.getColor(R.color.stop_received);
 35         // Set up UI.
 36         mShowStartView = (TextView) findViewById(R.id.onstart_textview);
 37         mShowStopView = (TextView) findViewById(R.id.onstop_textview);
 38         mParamsTextView = (TextView) findViewById(R.id.task_params);
 39         mDelayEditText = (EditText) findViewById(R.id.delay_time);
 40         mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
 41         mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
 42         mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
 43         mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
 44         mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
 45         mServiceComponent = new ComponentName(this, TestJobService.class);
 46         // Start service and provide it a way to communicate with us.
 47         Intent startServiceIntent = new Intent(this, TestJobService.class);
 48         startServiceIntent.putExtra("messenger", new Messenger(mHandler));
 49        startService(startServiceIntent);
 50     }
 51
 52     Handler mHandler = new Handler(/* default looper */) {
 53         @Override
 54         public void handleMessage(Message msg) {
 55             switch (msg.what) {
 56                 case MSG_UNCOLOUR_START:
 57                     mShowStartView.setBackgroundColor(defaultColor);
 58                     break;
 59                 case MSG_UNCOLOUR_STOP:
 60                     mShowStopView.setBackgroundColor(defaultColor);
 61                     break;
 62                 case MSG_SERVICE_OBJ:
 63                     mTestService = (TestJobService) msg.obj;
 64                     mTestService.setUiCallback(MainActivity.this);
 65             }
 66         }
 67     };
 68
 69     private boolean ensureTestService() {
 70         if (mTestService == null) {
 71             Toast.makeText(MainActivity.this, "Service null, never got callback?",
 72                     Toast.LENGTH_SHORT).show();
 73             return false;
 74         }
 75         return true;
 76     }
 77
 78     /**
 79      * UI onclick listener to schedule a job. What this job is is defined in
 80      * TestJobService#scheduleJob().
 81      */
 82     @SuppressLint("NewApi")
 83     public void scheduleJob(View v) {
 84         if (!ensureTestService()) {
 85             return;
 86         }
 87         JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
 88
 89         String delay = mDelayEditText.getText().toString();
 90         if (delay != null && !TextUtils.isEmpty(delay)) {
 91             builder.setMinimumLatency(Long.valueOf(delay) * 1000);
 92         }
 93         String deadline = mDeadlineEditText.getText().toString();
 94         if (deadline != null && !TextUtils.isEmpty(deadline)) {
 95             builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
 96         }
 97         boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
 98         boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
 99         if (requiresUnmetered) {
100             builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
101         } else if (requiresAnyConnectivity) {
102             builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
103         }
104         builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
105         builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
106        mTestService.scheduleJob(builder.build());
107     }
108     /**
109      * cancel All jobs
110      * @param v
111      */
112     @SuppressLint("NewApi")
113     public void cancelAllJobs(View v) {
114         JobScheduler tm =
115                 (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
116         tm.cancelAll();
117     }
118
119     /**
120      * UI onclick listener to call jobFinished() in our service.
121      */
122     public void finishJob(View v) {
123         if (!ensureTestService()) {
124             return;
125         }
126         mTestService.callJobFinished();
127         mParamsTextView.setText("");
128     }
129
130     /**
131      * Receives callback from the service when a job has landed
132      * on the app. Colours the UI and post a message to
133      * uncolour it after a second.
134      */
135     @SuppressLint("NewApi")
136     public void onReceivedStartJob(JobParameters params) {
137         mShowStartView.setBackgroundColor(startJobColor);
138         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
139         mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
140         mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
141     }
142
143     /**
144      * Receives callback from the service when a job that
145      * previously landed on the app must stop executing.
146      * Colours the UI and post a message to uncolour it after a
147      * second.
148      */
149     public void onReceivedStopJob() {
150         mShowStopView.setBackgroundColor(stopJobColor);
151         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
152         mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
153         mParamsTextView.setText("");
154     }
155
156 }

对于这个Demo我只想说一个点,MainActivity在启动的时候onCreate()方法中47-49行启动了TestJobService,并且传递了一个new Messenger(mHandler)匿名对象,接下来我们看下TestJobService中onStartCommand方法,此方法上来就获取Messenger对象,并且调用send方法发送一个消息(实际调用的就是Handler的send方法,可自行点进源码查看),此消息obj为TestJobService类实例对象。回到MainActivity中查看mHandler,what为MSG_SERVICE_OBJ的时候:将msg的obj赋值给MainActivity中mTestService变量,然后调用TestJobService中setUiCallback方法,这样MainActivity与TestJobService类就互相持有彼此实例对象了,也就可以调用其内部的方法互相通信了,比如TestJobService中onStartJob方法调用MainActivity中的onReceivedStartJob方法,onReceivedStartJob方法中其实就是发送了Handler消息,最后在Handler中执行相关业务逻辑。好了Demo就说这一点,其余请自行细细查看,很简单,最后附上Demo布局文件:

  1 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  2     android:layout_width="match_parent"
  3     android:layout_height="match_parent"
  4     android:orientation="vertical" >
  5
  6     <LinearLayout
  7         android:layout_width="match_parent"
  8         android:layout_height="match_parent"
  9         android:layout_weight="1"
 10         android:orientation="vertical">
 11
 12         <LinearLayout
 13             android:layout_width="match_parent"
 14             android:layout_height="100dp">
 15             <TextView
 16                 android:id="@+id/onstart_textview"
 17                 android:layout_width="wrap_content"
 18                 android:layout_height="match_parent"
 19                 android:layout_weight="1"
 20                 android:background="#999999"
 21                 android:gravity="center"
 22                 android:text="@string/onstarttask"/>
 23             <TextView
 24                 android:id="@+id/onstop_textview"
 25                 android:layout_width="wrap_content"
 26                 android:layout_height="match_parent"
 27                 android:layout_weight="1"
 28                 android:background="@color/none_received"
 29                 android:gravity="center"
 30                 android:text="@string/onstoptask"/>
 31         </LinearLayout>
 32         <Button
 33             android:id="@+id/finished_button"
 34             android:layout_width="match_parent"
 35             android:layout_height="wrap_content"
 36             android:padding="20dp"
 37             android:layout_marginBottom="5dp"
 38             android:onClick="finishJob"
 39             android:text="@string/finish_job_button_text"/>
 40
 41         <TextView
 42             android:id="@+id/task_params"
 43             android:layout_width="match_parent"
 44             android:layout_height="wrap_content"
 45             android:text="@string/defaultparamtext"
 46             android:gravity="center"
 47             android:textSize="20dp"
 48             android:padding="15dp"
 49             android:layout_marginBottom="10dp" />
 50
 51         <TextView
 52             android:layout_width="match_parent"
 53             android:layout_height="wrap_content"
 54             android:text="@string/constraints"
 55             android:layout_margin="15dp"
 56             android:textSize="18dp"/>
 57         <LinearLayout
 58             android:layout_width="match_parent"
 59             android:layout_height="wrap_content"
 60             android:orientation="vertical"
 61             android:layout_marginLeft="10dp">
 62             <LinearLayout
 63                 android:layout_width="match_parent"
 64                 android:layout_height="wrap_content">
 65                 <TextView
 66                     android:layout_width="wrap_content"
 67                     android:layout_height="wrap_content"
 68                     android:text="@string/connectivity"
 69                     android:layout_marginRight="10dp"/>
 70                 <RadioGroup
 71                     android:layout_width="wrap_content"
 72                     android:layout_height="wrap_content"
 73                     android:orientation="horizontal">
 74                     <RadioButton android:id="@+id/checkbox_any"
 75                         android:layout_width="wrap_content"
 76                         android:layout_height="wrap_content"
 77                         android:text="@string/any"
 78                         android:checked="false" />
 79                     <RadioButton android:id="@+id/checkbox_unmetered"
 80                         android:layout_width="wrap_content"
 81                         android:layout_height="wrap_content"
 82                         android:text="@string/unmetered"
 83                         android:checked="false" />
 84                 </RadioGroup>
 85
 86             </LinearLayout>
 87             <LinearLayout
 88                 android:layout_width="match_parent"
 89                 android:layout_height="wrap_content">
 90                 <TextView
 91                     android:layout_width="wrap_content"
 92                     android:layout_height="wrap_content"
 93                     android:text="@string/timing"/>
 94                 <TextView
 95                     android:layout_width="wrap_content"
 96                     android:layout_height="wrap_content"
 97                     android:layout_marginLeft="15dp"
 98                     android:textSize="17dp"
 99                     android:text="@string/delay"/>
100                 <EditText
101                     android:id="@+id/delay_time"
102                     android:layout_width="60dp"
103                     android:layout_height="wrap_content"
104                     android:inputType="number"/>
105                 <TextView
106                     android:layout_width="wrap_content"
107                     android:layout_height="wrap_content"
108                     android:text="@string/deadline"
109                     android:textSize="17dp"/>
110                 <EditText
111                     android:id="@+id/deadline_time"
112                     android:layout_width="60dp"
113                     android:layout_height="wrap_content"
114                     android:inputType="number"/>
115             </LinearLayout>
116             <LinearLayout
117                 android:layout_width="match_parent"
118                 android:layout_height="wrap_content">
119                 <TextView
120                     android:layout_width="wrap_content"
121                     android:layout_height="wrap_content"
122                     android:text="@string/charging_caption"
123                     android:layout_marginRight="15dp"/>
124                 <CheckBox
125                     android:layout_width="wrap_content"
126                     android:layout_height="wrap_content"
127                     android:id="@+id/checkbox_charging"
128                     android:text="@string/charging_text"/>
129             </LinearLayout>
130             <LinearLayout
131                 android:layout_width="match_parent"
132                 android:layout_height="wrap_content">
133                 <TextView
134                     android:layout_width="wrap_content"
135                     android:layout_height="wrap_content"
136                     android:text="@string/idle_caption"
137                     android:layout_marginRight="15dp"/>
138                 <CheckBox
139                     android:layout_width="wrap_content"
140                     android:layout_height="wrap_content"
141                     android:id="@+id/checkbox_idle"
142                     android:text="@string/idle_mode_text"/>
143             </LinearLayout>
144
145         </LinearLayout>
146         <Button
147             android:id="@+id/schedule_button"
148             android:layout_width="match_parent"
149             android:layout_height="wrap_content"
150             android:layout_marginTop="20dp"
151             android:layout_marginLeft="40dp"
152             android:layout_marginRight="40dp"
153             android:onClick="scheduleJob"
154             android:text="@string/schedule_job_button_text"/>
155         <Button
156             android:id="@+id/cancel_button"
157             android:layout_width="match_parent"
158             android:layout_height="wrap_content"
159             android:layout_marginLeft="40dp"
160             android:layout_marginRight="40dp"
161             android:onClick="cancelAllJobs"
162             android:text="@string/cancel_all_jobs_button_text"/>
163     </LinearLayout>
164 </ScrollView>

好了,本篇到此结束,希望通过本篇介绍你能正确使用JobScheduler这个强大的工具,有些任务放在适合的时机来做更加适宜。

原文地址:https://www.cnblogs.com/leipDao/p/8268918.html

时间: 2024-10-20 12:47:13

安卓电量优化之JobScheduler使用介绍的相关文章

安卓电量优化之WakeLock锁机制全面解析

一.WakeLock概述 wakelock是一种锁的机制,只要有应用拿着这个锁,CPU就无法进入休眠状态,一直处于工作状态.比如,手机屏幕在屏幕关闭的时候,有些应用依然可以唤醒屏幕提示用户消息,这里就是用到了wakelock锁机制,虽然手机屏幕关闭了,但是这些应用依然在运行着.手机耗电的问题,大部分是开发人员没有正确使用这个锁,成为"待机杀手". Android手机有两个处理器,一个叫Application Processor(AP),一个叫Baseband Processor(BP)

安卓性能优化 视频

韩梦飞沙  韩亚飞  [email protected]  yue31313  han_meng_fei_sha 安卓-性能优化之内存泄漏-原创-高清视频-爱奇艺 ========= Android手机内存管理与性能优化视频教程下载 下载:http://pan.baidu.com/s/1skkSdI1密码:kdcs 01.Dalvik介绍及其优势和文件格式 02.基于栈与基于寄存器比较 03.DEX与ODEX文件格式和ODEX化详解 04.GC垃圾回收机制 05.内存监测分析工具DDMS介绍 0

Android电量优化

最近领导老是反映说我们的APP耗电要比以前厉害一些,排在耗电量的首位,上黑名单了,需要进行电量优化!经过一段时间的研究,自己做了一部分的总结! 电量优化的工具battery-historien battery-historien是google开源的电量检测分析的工具,由于很多APP开发者对电量这快关注不是那么多,star数并不是特别多! 链接:https://github.com/google/battery-historian上面有具体环境搭建步骤! 环境搭建步骤 我使用的是方法二,步骤如下:

Hive语法层面优化之一数据倾斜介绍

数据倾斜:数据分布不均匀,造成数据大量的集中到一点,造成数据热点: 由于数据并不是平均分配的,会导致各个节点上处理的数据量是不均衡的,所以数据倾斜是无法避免的: 造成数据倾斜的最根本原因:key分发不均匀造成的: 常见的数据倾斜的症状 1)  Map阶段快,reduce阶段非常慢: 2)  某些map很快,某些map很慢: 3)  某些reduce很快,某些reduce很慢: 4)  任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成,

ReSharper的功能真的很强大主要是针对代码规范和优化,园子里介绍的也不少,如果你没有安装,那我只能表示你们会相见恨晚

二.ReSHarper 代码规范.单元测试.... ReSharper的功能真的很强大,主要是针对代码规范和优化,园子里介绍的也不少,如果你没有安装,那我只能表示你们会相见恨晚! 1.像命名不规范,foreach转化为linq, 用var来命名,出名的Ctrl+alt+Enter 自动修改,清除多余的变量和引用,Ctrl+K+D(这是VS自带的,搞错了)文档对齐,Ctrl+R+R 命名替换 等等我就不再多说了.用过的人都知道. 2.关键是这个货居然还能调整CSS. 比如: 比自己敲要来的快,当然

安卓手机优化 ROOT自启动管理 + 电量管理

一.KingRoot + 净化大师 KingRoot 主要完成ROOT 和 自启动软件的管理 这里禁止的自启动管理 对于有些软件是不太管用 比如美团 手机百度等 净化大师 主要完成 高电量的软件优化 还有禁止顽固的自启动程序  比如美团等 经过这两个软件的优化 重启手机速度变的很快了,然后在[设置]-[应用程序]-[正在运行]里查看现在的软件自启动情况

安卓性能优化手册

本手册适合至少有初级经验的开发者查阅或复习相关知识使用,新手可能会看不懂. 1.java代码优化 1.1安卓如何执行代码 dvm:.java->.class->.dex->.apk 优化斐波那契数列: 斐波那契数列的递推公式是f(n)=f(n-1)+f(n-2),特征方程为:x2=x+1,解该方程得(1+sqrt(5))/2,(1-sqrt(5))/2.所以f(n)=Ax1n+Bx2n,带入f(0)=0,f(1)=1得A=sqrt(5)/5,B=-sqrt(5)/5.则f(n)求出. B

Android-电量优化

Android手机和iphone相比较起来,运行以及耗电都没有iphone体验更好.主要是Android的多任务机制问题.最直观的就是很多Android手机出厂就会带上清理垃圾,清理内存的软件.会有一键清理释放内存功能.但是在iphone上你是看不到的. Android:为了提高手机运行速度或者是有强迫症的,就会经常一键清理.99%的用户手机上几乎都安装一个优化软件或原厂或第三方.没有使用任何优化软件的用户一夜待机手机耗电就会很高. Iphone:不用总去杀进程你也不会感觉到卡,正常来说不用安装

性能优化之电量优化2-使用Battery Historian生成电量消耗报告

1 数据准备 1.1 先断开adb服务,然后开启adb服务 (a)adb kill-server 这一步很重要,因为当我们开发时做电量记录时会打开很多可能造成冲突的东西.为了保险起见我们重启adb.adb devices就会自动连接查找手机. 备注:mac可以直接使用adb命令:但是windows不行,需要进入到adt下:adt-bundle-windows-x86_64-20140702\adt-bundle-windows-x86_64-20140702\sdk\platform-tools