Android架构组件WorkManager(管理后台任务)使用

WorkManager定义:

WorkManager API可以轻松地让异步任务延迟执行以及何时运行它们,这些API可让我们创建任务并将其交给WorkManager,以便立即或在适当的时间运行。例如,应用程序可能需要不时从网络下载新资源,我们可以使用WorkManager API设置一个任务,然后选择适合它运行的环境(例如“仅在设备充电和联网时”),并在符合条件时将其交给 WorkManager 运行,即使该应用程序被强制退出或者设备重新启动,这个任务仍然可以保证运行

WorkManager适用于那些即使应用程序退出,系统也能够保证这个任务正常运行的场景,比如将应用程序数据上传到服务器。它不适用于应用进程内的后台工作,如果应用进程消失,就可以安全地终止,对于这种情况,需要选择ThreadPool、AsyncTask来实现。

Work的约束:

 .setRequiredNetworkType(NetworkType.CONNECTED)//网络连接时执行
 .setRequiresBatteryNotLow(true) //不在电量不足执行
 .setRequiresCharging(true) //在充电时执行
 .setRequiresStorageNotLow(true) //不在存储容量不足时执行
 .setRequiresDeviceIdle(true) //在待机状态下执行 调用需要API级别最低为23

Work设置网络约束时的 各个值类型的作用

 NetworkType.NOT_REQUIRED:对网络没有要求
 NetworkType.CONNECTED:网络连接的时候执行
 NetworkType.UNMETERED:不计费的网络比如WIFI下执行
 NetworkType.NOT_ROAMING:非漫游网络状态
 NetworkType.METERED:计费网络比如3G,4G下执行。

开始创建Work

package io.dcloud.H56580E2E.viewModelLiveData;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.gson.Gson;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.work.Data;
import androidx.work.Worker;
import io.dcloud.H56580E2E.R;
import io.dcloud.H56580E2E.info.ImageInfo;
import io.dcloud.H56580E2E.service.MainInterfaceService;
import io.dcloud.H56580E2E.util.BaseObserver;
import io.dcloud.H56580E2E.util.RetrofitHelper;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class DomeWork extends Worker {
    // 服务请求接口
    private MainInterfaceService main_interfaceService;
    @NonNull
    @Override
    public WorkerResult doWork() {
        /**
         * WorkerResult.SUCCESS //成功
         * WorkerResult.FAILURE //失败
         * WorkerResult.RETRY //重试
         */

        //接收传递进来的参数
        String parame_str = this.getInputData().getString("workparame","");
        Log.i("work","任务执行了"+parame_str);

        main_interfaceService = RetrofitHelper.getInstance().create(MainInterfaceService.class);

        //执行网络请求
        getShufflingImageRequest();
        //回传参数
        String return_parame = "回传参数001";
        Data data = new Data.Builder().putString("returnparame",return_parame).build();
        setOutputData(data);

        return WorkerResult.SUCCESS;
    }

    /**
     * 网络请求,测试接口 使用的是 Rxjava2+RxAndroid+ReTrofit2 请求框架
     */
    private void getShufflingImageRequest(){
        main_interfaceService.getShufflingImage()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()) //因为下面要发送通知所以必须在请求完成的时候把线程切换到 main 主线程中
                .subscribe(new BaseObserver() {
                    @Override
                    protected void onFailure(Throwable e, boolean isNetWorkError) throws Exception {
                        //请求失败
                        Log.i("work","服务请求失败");
                    }

                    @Override
                    protected void onSuccees(ImageInfo imageInfo) throws Exception {
                        //请求成功
                        Gson gson = new Gson();
                        String data_str = gson.toJson(imageInfo);
                        Log.i("work","返回的数据"+data_str);
                        sendNotification();//发送通知
                    }
                });
    }

    /**
     * 发送一个通知
     */
    private void sendNotification(){
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(),"default");
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
        mBuilder.setContentTitle("我的work测试");//设置内容标题
        mBuilder.setContentText("work执行完毕发送通知");//设置内容
        mBuilder.setTicker("您有新的消息了");//通知弹出时状态栏的提示文本
        mBuilder.setDefaults(Notification.DEFAULT_SOUND);//设置声音震动
        mBuilder.setAutoCancel(true);//设置通知的点击行为,自动取消/跳转等

        //创建一个意图
        Intent intent = new Intent(getApplicationContext(),DomeActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),0,intent,PendingIntent.FLAG_CANCEL_CURRENT);
        mBuilder.setContentIntent(pendingIntent);

        //获取通知管理对象
        NotificationManager mNotificaionManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificaionManager.notify(0,mBuilder.build());
    }
}

在Activity中使用

package io.dcloud.H56580E2E.viewModelLiveData;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.State;
import androidx.work.WorkContinuation;
import androidx.work.WorkManager;
import androidx.work.WorkStatus;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.dcloud.H56580E2E.R;
import io.reactivex.functions.Consumer;

import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.jakewharton.rxbinding3.view.RxView;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class DomeActivity extends AppCompatActivity {
   
    //Work请求
    private OneTimeWorkRequest domeWork;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dome);
        //Work执行
        performWork();
    }

    /**
     * 第一种.创建单个的 Work 任务
     */
    private void performWork() {
        //添加约束条件
       /* Constraints myconstrain = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)//网络连接时执行
                .setRequiresBatteryNotLow(true) //不在电量不足执行
                .setRequiresCharging(true) //在充电时执行
                .setRequiresStorageNotLow(true) //不在存储容量不足时执行
                .setRequiresDeviceIdle(true) //在待机状态下执行 调用需要API级别最低为23
                .build();*/

        /**添加约束条件(网路连接时执行)
         * 指定网络状态执行任务
         * NetworkType.NOT_REQUIRED:对网络没有要求
         * NetworkType.CONNECTED:网络连接的时候执行
         * NetworkType.UNMETERED:不计费的网络比如WIFI下执行
         * NetworkType.NOT_ROAMING:非漫游网络状态
         * NetworkType.METERED:计费网络比如3G,4G下执行。
         */
        Constraints mycoustrain = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED).build();
        //传入参数(import androidx.work.Data)
        Data data = new Data.Builder().putString("workparame", "workHelloWorld").build();
        //构造work
        domeWork = new OneTimeWorkRequest.Builder(DomeWork.class).setConstraints(mycoustrain).setInputData(data).build();
        //放入执行队列
        WorkManager.getInstance().enqueue(domeWork);

        /**
         * 任务执行状态的监听,可以获取到任务回传的参数
         */
        WorkManager.getInstance().getStatusById(domeWork.getId())
                .observe(this, new Observer() {
                    @Override
                    public void onChanged(WorkStatus workStatus) {
                        if (workStatus == null) {
                            return;
                        }
                        if (workStatus.getState() == State.ENQUEUED) {
                            //任务入列
                            Log.i("work", "任务入列");
                        }
                        if (workStatus.getState() == State.RUNNING) {
                            //任务正在执行
                            Log.i("work", "任务正在执行");
                        }
                        if (workStatus.getState().isFinished()) {
                            //任务执行完毕
                            Log.i("work", "任务执行完毕");
                            //接收回传的参数
                            Data outData = workStatus.getOutputData();
                            String out_parame = outData.getString("returnparame", "");
                            Toast.makeText(DomeActivity.this, "返回的参数" + out_parame, Toast.LENGTH_LONG).show();
                        }
                    }
                });

    }

    /**
     * 第二种.创建可以重复执行的任务(15m执行一次)
     */
    public void cycleWork() {
        //传入参数(import androidx.work.Data)
        Data data = new Data.Builder().putString("workparame", "workHelloWorld").build();
        //要创建循环任务,要使用PeriodicWorkRequest.Builder类创建一个PeriodicWorkRequest对象,然后将PeriodicWorkRequest以与OneTimeWorkRequest对象相同的方式入列
        //任务15m循环(源码里面已经规定了最小时间间隔15分钟)
        PeriodicWorkRequest.Builder invDomeWork = new PeriodicWorkRequest.Builder(DomeWork.class, 15, TimeUnit.MINUTES).setInputData(data);//每 15m 执行一次
        PeriodicWorkRequest invWork = invDomeWork.build();
        WorkManager.getInstance().enqueue(invWork);
        
        //其它方法同第一种。。。
    }

    /**
     * 第三种.创建链式任务
     */
    public void chainWork() {
        //添加约束条件(网路连接时执行)
        Constraints mycoustrain = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED).build();
        //传入参数(import androidx.work.Data)
        Data data = new Data.Builder().putString("worktest", "workHelloWorld").build();
        OneTimeWorkRequest oneA = new OneTimeWorkRequest.Builder(DomeWork.class).setConstraints(mycoustrain).setInputData(data).build();
        OneTimeWorkRequest oneB = new OneTimeWorkRequest.Builder(DomeWork2.class).build();
        OneTimeWorkRequest oneC = new OneTimeWorkRequest.Builder(DomeWork3.class).setConstraints(mycoustrain).setInputData(data).build();
        OneTimeWorkRequest oneD = new OneTimeWorkRequest.Builder(DomeWork4.class).setConstraints(mycoustrain).setInputData(data).build();
        OneTimeWorkRequest oneE = new OneTimeWorkRequest.Builder(DomeWork5.class).setConstraints(mycoustrain).setInputData(data).build();

        /*******************************************************************以下三种运行时只能选择一种********************************************************************/
        //1.行顺序为 oneA -> oneB -> oneC
        //WorkManager根据每个任务的指定约束以请求的顺序运行任务,如果任何任务返回Worker.WorkerResult.FAILURE,则整个序列结束。
       WorkManager.getInstance().beginWith(oneA)
                .then(oneB)
                .then(oneC).enqueue();

        //2.执行顺序为 oneA 和 oneB 并行  oneA,oneB任务完成后执行 oneC
        WorkManager.getInstance().beginWith(oneA,oneB)
                .then(oneC).enqueue();

        //3.创建复杂任务链  任务链chain1 与 chain2 并行  chain1和chain2完成后执行 oneE任务
        // (在oneB之前运行oneA,它也在oneD之前运行oneC, oneB和oneD都完成后,WorkManager 运行oneE)
       WorkContinuation chain1 = WorkManager.getInstance().beginWith(oneA).then(oneB);//创建 任务链1
        WorkContinuation chain2 = WorkManager.getInstance().beginWith(oneC).then(oneD);//创建 任务链2
        WorkContinuation chain3 = WorkContinuation.combine(chain1,chain2).then(oneE);//创建 任务链3
        chain3.enqueue();

       //其它方法同第一种。。。

    }

    /**
     * 取消Work 任务
     */
    private void cancelWork() {
        //获取任务的Work ID
        UUID comperssionWorkId = domeWork.getId();
        WorkManager.getInstance().cancelWorkById(comperssionWorkId);
    }

}

你可能感兴趣的:(Android)