做視頻點(diǎn)播網(wǎng)站如何賺錢seo云優(yōu)化方法
相關(guān)文章
【重生之我在學(xué)Android原生】ContentProvider(Java)
【重生之我在學(xué)Android原生】Media3
【重生之我在學(xué)Android】WorkManager (章一)
前言
官方文檔
官方推薦 - 前臺服務(wù)、后臺服務(wù)都可以使用WorkManger來實(shí)現(xiàn)
案例
語言:JAVA
實(shí)現(xiàn)要求
一步步實(shí)現(xiàn)一個(gè)圖片壓縮APP
創(chuàng)建項(xiàng)目
添加WorkManager依賴
參考文章
添加到builder.gradle, sync一下
val workVersion = "2.9.0"implementation("androidx.work:work-runtime:$workVersion")
接收share來的圖片數(shù)據(jù)
要實(shí)現(xiàn)這種效果,需要在AndroidManifest.xml聲明標(biāo)簽,過濾intent
<intent-filter><action android:name="android.intent.action.SEND" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="image/*" /></intent-filter>
將Activity改為singleTop
運(yùn)行APP。打開手機(jī)相冊,分享一張圖片,會(huì)重新使用這個(gè)Activity
android:launchMode="singleTop"
在onNewIntent接收數(shù)據(jù)
定義Worker
你需要做什么事情,你就定義一個(gè)Worker,指派它做事,做什么事,就在dowork里定義
dowork有三個(gè)返回,見圖
傳入U(xiǎn)ri到Worker
參考這里
通過inputdata傳入
Uri -> Bitmap
若有爆紅位置
壓縮圖片直到圖片的大小不超過XKB
傳入圖片的大小閥值
不斷循環(huán)壓縮,一直到圖片的大小不超過20KB
生成文件
返回圖片地址數(shù)據(jù)
構(gòu)建Data,傳值回去
監(jiān)聽Worker結(jié)果
在獲取到WorkManager這個(gè)實(shí)例后
通過getWorkInfoByIdLiveData方法來監(jiān)聽workerrequest狀態(tài)及結(jié)果返回
顯示結(jié)果
在布局中,加入一張圖片
Android版本 兼容問題
兼容低版本的Android系統(tǒng)
inputStream.readAllBytes() 需要在API 33之后使用
所以需要更改寫法,來使低版本的Android系統(tǒng)使用
bytes = new byte[inputStream.available()];inputStream.read(bytes);
運(yùn)行項(xiàng)目
完整代碼
// ImageCompressionWorker
package com.test.imagecompressionworkerapplication;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.util.Log;import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;public class ImageCompressionWorker extends Worker {private final String TAG = "worker - log";public static final String KEY_CONTENT_URI = "KEY_CONTENT_URI";public static final String KEY_COMPRESSION_THRESHOLD = "KEY_COMPRESSION_THRESHOLD";public static final String KEY_RESULT_PATH = "KEY_RESULT_PATH";private final WorkerParameters workerParameters;private final Context appContext;public ImageCompressionWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {super(context, workerParams);appContext = context;workerParameters = workerParams;}@NonNull@Overridepublic Result doWork() {Data inputData = workerParameters.getInputData();String uriStr = inputData.getString(KEY_CONTENT_URI);long size = inputData.getLong(KEY_COMPRESSION_THRESHOLD, 0L);assert uriStr != null;Uri uri = Uri.parse(uriStr);byte[] bytes;try {InputStream inputStream = appContext.getContentResolver().openInputStream(uri);assert inputStream != null;
// byte[] bytes_ = inputStream.readAllBytes();bytes = new byte[inputStream.available()];inputStream.read(bytes);Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);inputStream.close();int quality = 100;byte[] byteArray;do {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);byteArray = byteArrayOutputStream.toByteArray();quality -= Math.round(quality * 0.1);} while (byteArray.length > size && quality > 5);File file = new File(appContext.getCacheDir(), workerParameters.getId() + ".jpg");FileOutputStream fileOutputStream = new FileOutputStream(file);fileOutputStream.write(byteArray);fileOutputStream.close();String absolutePath = file.getAbsolutePath();Data outputData = new Data.Builder().putString(KEY_RESULT_PATH, absolutePath).build();return Result.success(outputData);} catch (IOException e) {throw new RuntimeException(e);}}
}
// MainActivity.java
package com.test.imagecompressionworkerapplication;import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;import java.util.UUID;public class MainActivity extends AppCompatActivity {private final String TAG = "mainActivity - log";private WorkManager workManager;private ImageView sharedImage;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);workManager = WorkManager.getInstance(this);bindView();}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);Uri uri;if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {uri = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri.class);} else {uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);}assert uri != null;long size = 1024 * 20L;Data inputData = new Data.Builder().putString(ImageCompressionWorker.KEY_CONTENT_URI, uri.toString()).putLong(ImageCompressionWorker.KEY_COMPRESSION_THRESHOLD, size).build();OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(ImageCompressionWorker.class).setInputData(inputData)
// .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST).build();workManager.enqueue(oneTimeWorkRequest);UUID id = oneTimeWorkRequest.getId();workManager.getWorkInfoByIdLiveData(id).observe(this, workInfo -> {if (workInfo.getState() == WorkInfo.State.SUCCEEDED) {Data outputData = workInfo.getOutputData();String filePath = outputData.getString(ImageCompressionWorker.KEY_RESULT_PATH);Bitmap bitmap = BitmapFactory.decodeFile(filePath);sharedImage.setImageBitmap(bitmap);}});}private void bindView() {sharedImage = findViewById(R.id.sharedImage);}
}
更多內(nèi)容
這一節(jié),有些流水賬,看看就好
可以直接看官方文檔吧
官方文檔
執(zhí)行加急工作
配額策略
加急工作 + CoroutineWorker + 通知
加急工作需要配合通知使用,否則會(huì)報(bào)錯(cuò)
將之前的繼承Worker改為CoroutineWorker
重寫方法getForegroundInfo
@Nullable@Overridepublic Object getForegroundInfo(@NonNull Continuation<? super ForegroundInfo> $completion) {return new ForegroundInfo(NOTIFICATION_ID, createNotification());}private Notification createNotification() {String CHANNEL_ID = "compressor_channel_id";String CHANNEL_NAME = "壓縮圖片通知通道";String NOTIFICATION_TITLE = "你有一個(gè)程序在壓縮圖片";int importance = NotificationManager.IMPORTANCE_HIGH;NotificationChannel notificationChannel;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {notificationChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);NotificationManager notificationManager = getSystemService(appContext, NotificationManager.class);assert notificationManager != null;notificationManager.createNotificationChannel(notificationChannel);}String NOTIFICATION_TEXT = "壓縮中...";Intent intent = new Intent(appContext, ImageCompressionWorker.class);PendingIntent pendingIntent = PendingIntent.getActivity(appContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);return new NotificationCompat.Builder(appContext, CHANNEL_ID).setContentTitle(NOTIFICATION_TITLE).setContentText(NOTIFICATION_TEXT).setSmallIcon(R.drawable.ic_launcher_background).setContentIntent(pendingIntent).build();}
通知
在Android 12 之前的版本運(yùn)行,會(huì)有通知顯示;
通知需要申請權(quán)限
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
private static final String[] PERMISSION_REQUIRED = new String[]{Manifest.permission.POST_NOTIFICATIONS};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);workManager = WorkManager.getInstance(this);bindView();if (!checkAllPermissions()) {requestPermissions(PERMISSION_REQUIRED, REQUEST_CODE);}}private boolean checkAllPermissions() {for (String permission : PERMISSION_REQUIRED) {int permissionCheck = ContextCompat.checkSelfPermission(this, permission);if (permissionCheck == PackageManager.PERMISSION_DENIED) {return false;}}return true;}
運(yùn)行項(xiàng)目
壓縮過程很快,壓縮完成之后,通知關(guān)閉了
調(diào)度定期工作
每間隔一小時(shí)的最后15分鐘工作一次
為了方便測試,這里使用15分鐘一次
WorkRequest uploadRequest = new PeriodicWorkRequest.Builder(PeriodicUploadLogWorker.class, 15, TimeUnit.MINUTES, 15, TimeUnit.MINUTES).build();WorkManager workManager = WorkManager.getInstance(this);workManager.enqueue(uploadRequest);
public class PeriodicUploadLogWorker extends Worker {private final String TAG = "periodic_upload_log";public PeriodicUploadLogWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {super(context, workerParams);}@NonNull@Overridepublic Result doWork() {uploadLog();return Result.success();}private void uploadLog() {Log.i(TAG, String.valueOf(System.currentTimeMillis()));}
}
工作約束
將工作延遲到滿足最佳條件時(shí)運(yùn)行
延遲工作
重試和退避政策
標(biāo)記工作
分配輸入數(shù)據(jù)
setInputData 傳入數(shù)據(jù)
getInputData 獲取數(shù)據(jù)
唯一工作
查詢工作
按id、name、tag查詢
WorkQuery
取消工作
鏈接工作
將每個(gè)Worker鏈接起來,按順序執(zhí)行。
還可以定義合并器
默認(rèn)合并器,變量名一致的,值采用最新的覆蓋前者
第二種,會(huì)保留返回的結(jié)果,會(huì)合并相同變量名到一個(gè)數(shù)組中