- 引入
//workmanager
api 'androidx.work:work-runtime:2.3.4'
- 創建工作處理器
public class UploadFileWorker extends Worker {
public UploadFileWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
String restUrl;
@NonNull
@Override
public Result doWork() {
//當前爲子線程
Data inputData = getInputData();
String file = inputData.getString("file");
Log.e("TTT", "file============" + file);
Map<String, Object> map = new ArrayMap<>();
map.put("searchContent", "");
map.put("size", 15);
map.put("current", 1);
PagingHttpClient.getInstance()
.get("home/paintingList", map, new PagingHttpCallback<Teacher>() {
@Override
protected void onNext(Teacher data) {
restUrl = data.toString();
Log.e("TTT", "restUrl============" + restUrl);
}
@Override
protected void onFail(int code, String message) {
restUrl = message;
}
});
if (TextUtils.isEmpty(restUrl)) {
return Result.failure();
} else {
Data outputData = new Data.Builder().putString("fileUrl", restUrl).build();
return Result.success(outputData);
}
}
}
- 調用
public class WorkManagerActivity extends AppCompatActivity {
private UUID mId1;
private UUID mId2;
private String fileUrl1;
private String fileUrl2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work_manager);
}
/**
* WorkerManager使用
* <p>
* PeriodicWorkRequest可以週期性的執行任務,OneTimeWorkRequest執行一次
*
* @param view
*/
@SuppressLint("RestrictedApi")
public void onWorkManagerStartClick(View view) {
List<OneTimeWorkRequest> workRequests = new ArrayList<>();
OneTimeWorkRequest request1 = getOneTimeWorkRequest("我是任務1");
mId1 = request1.getId();
workRequests.add(request1);
OneTimeWorkRequest request2 = getOneTimeWorkRequest("我是任務2");
mId2 = request2.getId();
workRequests.add(request2);
WorkContinuation workContinuation = WorkManager.getInstance(this).beginWith(workRequests);
workContinuation.enqueue();
/**
* 接收回調
*/
// WorkManager.getInstance(this).getWorkInfoByIdLiveData(mId1)
workContinuation.getWorkInfosLiveData().observe(this, new Observer<List<WorkInfo>>() {
@Override
public void onChanged(List<WorkInfo> workInfos) {
//block runing enuqued failed susscess finish
int completedCount = 0;
for (WorkInfo workInfo : workInfos) {
WorkInfo.State state = workInfo.getState();
UUID id = workInfo.getId();
if (state == WorkInfo.State.FAILED) {
if (id.equals(mId1)) {
Toast.makeText(AppGlobals.getApplication(), "任務1失敗", Toast.LENGTH_LONG).show();
} else if (id.equals(mId2)) {
Toast.makeText(AppGlobals.getApplication(), "任務2失敗", Toast.LENGTH_LONG).show();
}
} else if (state == WorkInfo.State.SUCCEEDED) {
Data outputData = workInfo.getOutputData();
String fileUrl = outputData.getString("fileUrl");
Log.e("TTT", fileUrl);
if (id.equals(mId1)) {
fileUrl1 = fileUrl;
} else if (id.equals(mId2)) {
fileUrl2 = fileUrl;
}
completedCount++;
}
}
if (completedCount >= workInfos.size()) {
Toast.makeText(AppGlobals.getApplication(), "任務完成了,可以幹其他的活了", Toast.LENGTH_LONG).show();
}
}
});
}
/**
* WorkerManager使用
* <p>
* PeriodicWorkRequest可以週期性的執行任務,OneTimeWorkRequest執行一次
* 一般處理像鬧鐘一樣的任務
*
* @param view
*/
public void onPeriodicWorkManagerStartClick(View view) {
PeriodicWorkRequest request = getPeriodicWorkRequest("我是定時任務");
mId1 = request.getId();
WorkManager.getInstance(this).enqueue(request);
}
@SuppressLint("RestrictedApi")
private OneTimeWorkRequest getOneTimeWorkRequest(String filePath) {
//Data本質是HashMap 但是大小爲10kb,這也說明了,只能傳遞基本數據類型和Array集合
Data inputData = new Data.Builder()
.putString("file", filePath)
.build();
Constraints constraints = new Constraints();
//設備存儲空間充足的時候 才能執行 ,>15%
constraints.setRequiresStorageNotLow(true);
//必須在執行的網絡條件下才能好執行,不計流量 ,wifi
constraints.setRequiredNetworkType(NetworkType.UNMETERED);
//設備的充電量充足的才能執行 >15%
constraints.setRequiresBatteryNotLow(true);
//只有設備在充電的情況下 才能允許執行
constraints.setRequiresCharging(true);
//只有設備在空閒的情況下才能被執行 比如息屏,cpu利用率不高
constraints.setRequiresDeviceIdle(true);
//workmanager利用contentObserver監控傳遞進來的這個uri對應的內容是否發生變化,當且僅當它發生變化了
//我們的任務纔會被觸發執行,以下三個api是關聯的
constraints.setContentUriTriggers(null);
//設置從content變化到被執行中間的延遲時間,如果在這期間。content發生了變化,延遲時間會被重新計算
//這個content就是指 我們設置的setContentUriTriggers uri對應的內容
constraints.setTriggerContentUpdateDelay(0);
//設置從content變化到被執行中間的最大延遲時間
//這個content就是指 我們設置的setContentUriTriggers uri對應的內容
constraints.setTriggerMaxContentDelay(0);
OneTimeWorkRequest request = new OneTimeWorkRequest
.Builder(UploadFileWorker.class)
.setInputData(inputData)
// .setConstraints(constraints)
//設置一個攔截器,在任務執行之前 可以做一次攔截,去修改入參的數據然後返回新的數據交由worker使用
// .setInputMerger(null)
//當一個任務被調度失敗後,所要採取的重試策略,可以通過BackoffPolicy來執行具體的策略
//BackoffPolicy.EXPONENTIAL:指數級增長,BackoffPolicy.LINEAR:線性增長
// .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.SECONDS)
//任務被調度執行的延遲時間
// .setInitialDelay(10, TimeUnit.SECONDS)
//設置該任務嘗試執行的最大次數
// .setInitialRunAttemptCount(2)
//設置這個任務開始執行的時間
//System.currentTimeMillis()
// .setPeriodStartTime(0, TimeUnit.SECONDS)
//指定該任務被調度的時間
// .setScheduleRequestedAt(0, TimeUnit.SECONDS)
//當一個任務執行狀態編程finish時,又沒有後續的觀察者來消費這個結果,難麼workamnager會在
//內存中保留一段時間的該任務的結果。超過這個時間,這個結果就會被存儲到數據庫中
//下次想要查詢該任務的結果時,會觸發workmanager的數據庫查詢操作,可以通過uuid來查詢任務的狀態
// .keepResultsForAtLeast(10, TimeUnit.SECONDS)
.build();
return request;
}
@SuppressLint("RestrictedApi")
private PeriodicWorkRequest getPeriodicWorkRequest(String filePath) {
//Data本質是HashMap 但是大小爲10kb,這也說明了,只能傳遞基本數據類型和Array集合
Data inputData = new Data.Builder()
.putString("file", filePath)
.build();
/**
* PeriodicWorkRequest可以週期性的執行任務,OneTimeWorkRequest執行一次
* repeatInterval 必須大於或等於 MIN_PERIODIC_INTERVAL_MILLIS = 15 * 60 * 1000L; // 15 minutes.
*/
PeriodicWorkRequest build = new PeriodicWorkRequest
.Builder(UploadFileWorker.class, 15, TimeUnit.MINUTES)
.setInputData(inputData)
.build();
return build;
}
@Override
protected void onDestroy() {
super.onDestroy();
WorkManager.getInstance(this).cancelAllWork();
// WorkManager.getInstance(this).cancelWorkById(mId1);
// WorkManager.getInstance(this).cancelWorkById(mId2);
}
}