美文网首页
浅谈性能优化-电量优化

浅谈性能优化-电量优化

作者: 大苏打6815 | 来源:发表于2019-05-21 18:28 被阅读0次
    电量测试

    电量测试:就是测试移动设备电量消耗快慢的一种测试方法。一般用平均电流来衡量电量消耗速度。平均电流越小,说明设备使用时间越长。但是平均电流多大才说明不耗电却没有一个统一标准。

    硬件测试:利用硬件设备测试被测设备的电流,统计一段时间内(使用某个功能模块)的平均电流值。

    软件测试:利用系统工具导出分析报告
    我们进行电量测试的时候,一般都是用软件测试的一种方式.

    安装流程有点复杂,就不在这里说了,这里主要是做代码分析,如果需要安装流程也可以私聊我

    WakeLock

    其实很多公司项目里面都适用WeakLock,这种方式并不一定好,对CPU的性能消耗比较大。

    电量优化(JobScheduler)

    以高德地图的Demo为例子,坐标是实实变化的,无时无刻不在上传到服务器,其实这种方法是非常耗电的。
    对于及时性挺高的功能,也可以使用闹钟。但是最好的办法就是使用 JobScheduler,它可以把一些不是特别紧急的任务放到更合适的时机批量处理。避免频繁的唤醒硬件模块,避免在不合适的时候执行一些耗时任务。我不可能每次接收到一个坐标就把一个坐标发送到服务器,这样发送没有必要。我们可以一次性整合到单次发送。JobScheduler是一个系统服务。以下是核心代码:仅仅是在充电情况下和wifi情况下才会执行这个服务。具体根据业务来

    public class JobManager {
    
        static JobManager instance;
        //把一些不是特别紧急(实时)的任务放到更合适的时机批量处理
        // 1、避免频繁的唤醒硬件模块
        // 2、避免在不合适的时候执行一些耗电的任务
        private JobScheduler jobScheduler;
        private Context context;
    
        private static final int jobId=0;
    
        public static JobManager getInstance() {
            if (null == instance)
                instance = new JobManager();
            return instance;
        }
    
        public void init(Context context) {
            this.context = context.getApplicationContext();
            jobScheduler = (JobScheduler)
                    context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    
        }
    
        /**
         * 添加一个任务
         * @param location
         */
        public void addJob(String location) {
            if (null == jobScheduler) {
                return;
            }
            JobInfo pendingJob = null;
            //整合多个job
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //查找id是0的job
                pendingJob = jobScheduler.getPendingJob(jobId);
            } else {
                List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
                for (JobInfo info : allPendingJobs) {
                    if (info.getId() == jobId) {
                        pendingJob = info;
                        break;
                    }
                }
            }
            //找到待执行的job
            if (null != pendingJob) {
                //多个坐标信息拼到一起 上传
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    //数据 与Intent 一样
                    PersistableBundle extras = pendingJob.getExtras();
                    //获得上一次设置的location数据
                    String data = extras.getString("DATA");
                    //比如 多条坐标数据用@隔开
                    location = data + "@" + location;
                    jobScheduler.cancel(jobId);
                }
            }
            // jobid :0
            PersistableBundle extras = new PersistableBundle();
            extras.putString("DATA",location);
            //创建一个job
            JobInfo jobInfo = new
                    JobInfo.Builder(jobId,
                    new ComponentName(context, MyJobService.class))
                    //只在充电的时候
                    .setRequiresCharging(true)
                    //不是蜂窝网络
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                    .setExtras(extras).build();
    
            //提交任务
            jobScheduler.schedule(jobInfo);
        }
    }
    
    public class MyJobService extends JobService {
    
        public static final String TAG = "MyJobService";
    
        @Override
        public boolean onStartJob(JobParameters params) {
            //如果返回值是false,这个方法返回时任务已经执行完毕。
            //如果返回值是true,那么这个任务正要被执行,我们就需要开始执行任务。
            //当任务执行完毕时你需要调用jobFinished(JobParameters params, boolean needsRescheduled)来通知系统
            new MyAsyncTask().execute(params);
            return true;
        }
    
        //当系统接收到一个取消请求时
        @Override
        public boolean onStopJob(JobParameters params) {
            //如果onStartJob返回false,那么onStopJob不会被调用
            // 返回 true 则会重新计划这个job
            return false;
        }
    
    
        /**
         * Params:启动任务时输入的参数类型.
         * <p>
         * Progress:后台任务执行中返回进度值的类型.
         * <p>
         * Result:后台任务执行完成后返回结果的类型.
         */
        class MyAsyncTask extends AsyncTask<JobParameters, Void, Void> {
            JobParameters jobParameters;
    
            @Override
            protected Void doInBackground(JobParameters[] objects) {
                jobParameters = objects[0];
                Log.i(TAG, jobParameters.getJobId() + " 任务开始执行......");
                PersistableBundle extras = jobParameters.getExtras();
                String location = extras.getString("DATA");
                Log.i(TAG, jobParameters.getJobId() + " 上传:" + location);
                HttpURLConnection conn = null;
                OutputStream os = null;
                try {
                    conn = (HttpURLConnection) new URL("https://www.baidu.com/")
                            .openConnection();
                    conn.setRequestMethod("POST");
                    conn.setDoOutput(true);
                    os = conn.getOutputStream();
                    os.write(location.getBytes());
                    os.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    Utils.safeColose(os);
                    if (null != conn) {
                        conn.disconnect();
                    }
                }
                return null;
            }
    
            /**
             * doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成.
             * <p>
             * onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作.
             * <p>
             * onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新.
             * <p>
             * onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法.通过此方法我们可以知晓任务的完成进度.
             */
            @Override
            protected void onPostExecute(Void s) {
                //当任务执行完毕之后,需要调用jobFinished来让系统知道这个任务已经结束,
                //系统可以将下一个任务添加到队列中
                //true表示需要重复执行
                //false反之
                jobFinished(jobParameters, false);
                Log.i(TAG, j  obParameters.getJobId() + "任务执行完成......");
            }
        }
    }
    
    记得在AndroidMainifest注册这个MyJobService 
    <service 
                android:name=".MyJobService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:process=":location" />
    
    

    在Application里面调用

     applicationt = this;
                location = new Intent(this, LocationService.class);
                startService(location);
    
    public class LocationService extends Service {
    
    //    private PowerManager.WakeLock locationLock;
        /*private Intent alarmIntent;*/
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            JobManager.getInstance().init(this);
            LocationManager.getInstance().startLocation(this);
            //使用WeakLock
    //        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            //判断是否支持
    //        pm.isWakeLockLevelSupported(PowerManager.PARTIAL_WAKE_LOCK);
            //只唤醒cpu
    //        locationLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
    //                "location_lock");
    //        locationLock.acquire();
    
          /*  alarmKeep();*/
        }
    
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            //释放
            LocationManager.getInstance().destoryLocation();
            //注销广播接收者
           /* unregisterReceiver(alarmReceiver);
    //        if (null != locationLock) {
    //            locationLock.release();
    //        }*/
        }
    
       /* private void alarmKeep() {
            alarmIntent = new Intent();
            alarmIntent.setAction("LOCATION");
            //创建延迟意图
            PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
            //获得闹钟管理器
            AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
            //动态注册广播接受者
            IntentFilter filter = new IntentFilter();
            filter.addAction("LOCATION");
            registerReceiver(alarmReceiver,filter);
            //设置一个 每隔 5s 发送一个广播
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,SystemClock.elapsedRealtime(),
                    5_000,broadcast);
        }*/
    
        /*BroadcastReceiver alarmReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (TextUtils.equals(intent.getAction(),"LOCATION")){
                    LocationManager.getInstance().startLocation(LocationService.this);
                }
            }
        };*/
    }
    
    初始化只是换了一种方式而已
    

    然后在高德地图API里面换一种写发,注意对应服务器地址,这里是随便写了一下


    image.png image.png

    相关文章

      网友评论

          本文标题:浅谈性能优化-电量优化

          本文链接:https://www.haomeiwen.com/subject/gaidzqtx.html