# Define the oom_adj values for the classes of processes that can be
# killed by the kernel. These are used in ActivityManagerService.
setprop ro.FOREGROUND_APP_ADJ 0 //前台进程
setprop ro.VISIBLE_APP_ADJ 1 //可见进程
setprop ro.SECONDARY_SERVER_ADJ 2 //次要服务
setprop ro.BACKUP_APP_ADJ 2 //备份进程
setprop ro.HOME_APP_ADJ 4 //桌面进程
setprop ro.HIDDEN_APP_MIN_ADJ 7 //后台进程
setprop ro.CONTENT_PROVIDER_ADJ 14 //内容供应节点
setprop ro.EMPTY_APP_ADJ 15 //空进程
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class WorkManagerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
// Initialize WorkManager with the default configuration.
WorkManager.initialize(getContext(), new Configuration.Builder().build());
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri,
@Nullable String[] projection,
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri,
@Nullable String selection,
@Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri,
@Nullable ContentValues values,
@Nullable String selection,
@Nullable String[] selectionArgs) {
return 0;
}
}
如果想要自定义初始化可以如下操作
//1. AndroidManifest.xml中覆盖其provider,并设置tools:node="remove"
//WorkManager 2.6以前版本
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
//WorkManager 2.6以后的版本
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
//2. Application实现Configuration.Provider接口
class MyApplication() : Application(), Configuration.Provider {
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.build()
}
//You do not need to call `WorkManager.initialize()` yourself
//注意这里是实现Provider接口而不是像2.1版本一样手动调用initialize,
//当然如果我就要手动调用WorkManager.initialize也不会有报错,只是官方不推荐
//看看WorkManagerImpl.getInstance方法就知道了
public static @NonNull WorkManagerImpl getInstance(@NonNull Context context) {
synchronized (sLock) {
WorkManagerImpl instance = getInstance();
if (instance == null) {
Context appContext = context.getApplicationContext();
//这里如果application没有实现Provider接口就直接抛出异常
if (appContext instanceof Configuration.Provider) {
initialize(
appContext,
((Configuration.Provider) appContext).getWorkManagerConfiguration());
instance = getInstance(appContext);
} else {
throw new IllegalStateException("WorkManager is not initialized properly. You "
+ "have explicitly disabled WorkManagerInitializer in your manifest, "
+ "have not manually called WorkManager#initialize at this point, and "
+ "your Application does not implement Configuration.Provider.");
}
}
return instance;
}
}
自定义Worker
谷歌提供了四种Worker给我们使用,分别为:
自动运行在后台线程的Worker
结合协程的CoroutineWorker
结合RxJava2的RxWorker
以上三个类的基类的ListenableWorker
我使用的是CoroutineWorker,然后重写doWork方法,其代码如下
class MyWorker(appContext: Context, workerParameters: WorkerParameters) :
CoroutineWorker(appContext, workerParameters) {
//执行在一个单独的后台线程里
override suspend fun doWork(): Result {
LjyLogUtil.d("doWork start")
delay(5000)//模拟处理任务耗时
LjyLogUtil.d("doWork end")
return Result.success()
}
}
val request1 = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
val request2 = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
val request3 = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
val request4 = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
val request5 = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
val workConstraints = WorkManager.getInstance(this).beginWith(request1)
workConstraints.then(request2).then(listOf(request3, request4)).enqueue()
workConstraints.then(request5).enqueue()
// by id
WorkManager.getInstance(this).getWorkInfoById(request1.id)
WorkManager.getInstance(this).getWorkInfoByIdLiveData(request1.id)
// by name
WorkManager.getInstance(this).getWorkInfosForUniqueWork("sync");
WorkManager.getInstance(this).getWorkInfosForUniqueWorkLiveData("sync");
// by tag
WorkManager.getInstance(this).getWorkInfosByTag("syncTag")
WorkManager.getInstance(this).getWorkInfosByTagLiveData("syncTag")
val workQuery = WorkQuery.Builder
.fromTags(listOf("syncTag"))
.addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
.addUniqueWorkNames(
listOf("preProcess", "sync")
)
.build()
val workInfos: ListenableFuture<List<WorkInfo>> =
WorkManager.getInstance(this).getWorkInfos(workQuery)
更新进度 和 观察进度
Java: 使用Worker.setProgressAsync()更新进度
Kotlin:使用 CoroutineWorker.setProgress()更新进度,代码如下
class MyWorker(appContext: Context, workerParameters: WorkerParameters) :
CoroutineWorker(appContext, workerParameters) {
override suspend fun doWork(): Result {
val name = inputData.getString("name")
LjyLogUtil.d("doWork start:name=$name")
val p0 = workDataOf("progressValue" to 0)
val p1 = workDataOf("progressValue" to 20)
val p2 = workDataOf("progressValue" to 40)
val p3 = workDataOf("progressValue" to 60)
val p4 = workDataOf("progressValue" to 80)
val p5 = workDataOf("progressValue" to 100)
setProgress(p0)
delay(1000)
setProgress(p1)
delay(1000)
setProgress(p2)
delay(1000)
setProgress(p3)
delay(1000)
setProgress(p4)
delay(1000)
setProgress(p5)
LjyLogUtil.d("doWork end")
return Result.success()
}
}