Androidでワークマネージャを使う
簡単に説明します.
カスタムワーナー
詳細説明here ワークマネージャ用
ドキュメントごとに
By default, WorkManager configures itself automatically when your app starts. If you require more control of how WorkManager manages and schedules work, you can customise the WorkManager configuration.
app.gradle
畝def work_version = "2.5.0"
implementation "androidx.work:work-runtime-ktx:$work_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
AndroidManifest.xml
畝<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
アプリケーションクラスを作成し、独自のカスタム設定を定義します.class TodoApplication() : Application(), Configuration.Provider {
override fun onCreate() {
super.onCreate()
// LATER PUT THE PERIODIC WORK REQUEST HERE
}
override fun getWorkManagerConfiguration(): Configuration {
return if (BuildConfig.DEBUG) {
Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).build()
}
else {
Configuration.Builder().setMinimumLoggingLevel(Log.ERROR).build()
}
}
}
Here, we use Configuration.Provider to extend our TodoApplication, and override the getWorkManagerConfiguration
この場合、ログレベルを設定します.カスタマイズ可能な一覧の一覧については
Configuration.Builder()
OneTimeWorkリクエスト
これは、我々のフォルダ構造がどのように見えるかです
アプリの労働者
任意の労働者を作成するには、次の手順が必要です.
WorkRequest
そして実行するこのファイルにはfileworkerが続き、このファイルはデバイスにファイルを作成し、タイムスタンプを新しく作成したファイルに追加する
ファイルワーク出力
OndemandBackupWorker
override suspend fun doWork(): Result {
val appContext = applicationContext
showNotifications("Backing up the data", appContext)
return try {
val res = dummyWork()
val outputData = workDataOf(KEY_ONDEMANDWORKER_RESP to res)
Result.success(outputData)
} catch (throwable: Throwable) {
Timber.e(throwable)
Result.failure()
}
}
private suspend fun dummyWork(): String {
// Faking the network call
sleep()
return "Completed successfully!"
}
Here, we create a dummyWork function, (which puts the thread to sleep) and returns string result.
workDataOf
(これはデータオブジェクトに対するペアのリストを、キーを使って変換します.Result.success
それは成功した作品を示しますResult.failure
畝ファイルワーカー
override fun doWork(): Result {
return try {
val content="Backed up on ${dateFormatter.format(Date())}"
val outputUri = saveToFile(appContext, content)
val data=workDataOf(KEY_FILEWORKER_RESP to outputUri.toString())
Result.success(data)
} catch (throwable: Throwable) {
Timber.e(throwable)
Result.failure()
}
}
Here, we create a file using saveToFile, and put in the current timestamp as text into that file
workDataOf
そして前のように、我々は労働者のResult.success
OnDemandBackupViewModel
internal fun beginBackup() {
val constraints = Constraints.Builder()
.setRequiresStorageNotLow(true)
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
var continuation = workManager.beginUniqueWork(
ONDEMAND_BACKUP_WORK_NAME,
ExistingWorkPolicy.KEEP,
OneTimeWorkRequest.from(OnDemandBackupWorker::class.java)
)
// BACKUP WORKER
val backupBuilder = OneTimeWorkRequestBuilder<OnDemandBackupWorker>()
backupBuilder.addTag(TAG_BACKUP)
backupBuilder.setConstraints(constraints)
continuation = continuation.then(backupBuilder.build())
// SAVE FILE WORKER
val saveInFile = OneTimeWorkRequest.Builder(FileWorker::class.java)
.setConstraints(constraints)
.addTag(TAG_FILE)
.build()
continuation = continuation.then(saveInFile)
continuation.enqueue()
}
internal fun cancelBackup() {
workManager.cancelUniqueWork(ONDEMAND_BACKUP_WORK_NAME)
}
beginUniqueWork
畝Since, we need to chain our work requests, hence we use
beginUniqueWork
ExistingWorkPolicy
オプションKEEP
OndemandBackupWorkerクラスからOneTimeWorkRequestを作成するbeginUniqueWork
は作業継続です.OneTimeWorkRequestBuilder
○○.私たちは、この仕事のためにタグを加えますWorkContinuation
畝enqueue
畝Note: For cancelling a work request, we simply call the
cancelUniqueWork
with the tag (used for creating the work)
ワークリクエストの進捗状況の追跡
WorkRequest
畝LiveData
それはWorkInfo
オブジェクト.WorkInfo
の現在の状態に関する詳細を含むオブジェクトですWorkRequest
畝internal val backupDataInfo: LiveData<List<WorkInfo>> = workManager
.getWorkInfosByTagLiveData(TAG_BACKUP)
Here,
TAG_BACKUP
is our tag, specified previously
定期的な要求
Note: PeriodicBackupWorker is the same like FileWorker (only difference is the file content)
Constraints
会う.PeriodicWorkRequest.Builder
val constraints = Constraints.Builder()
.setRequiresStorageNotLow(true)
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
val periodicBackup = PeriodicWorkRequestBuilder<PeriodicBackupWorker>(1, TimeUnit.DAYS)
.addTag(TAG_PERIODIC_BACKUP)
.setConstraints(constraints)
.build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
PERIODIC_BACKUP_WORK_NAME,
ExistingPeriodicWorkPolicy.KEEP,
periodicBackup
)
PeriodicWorkRequestBuilder
, 我々の作成PeriodicWorkRequest
畝Periodic work has a minimum interval of 15 minutes. Also if your periodic work has constraints, it will not execute until the constraints are met, even if the delay between periods has been met.
PeriodicWorkRequest
使用enqueueUniquePeriodicWork
, 作業方針の維持Keep
畝The normal lifecycle of a PeriodicWorkRequest is
ENQUEUED -> RUNNING -> ENQUEUED
従業員の筆記試験
我々は、現在我々の労働者のためにテストを書きます:
OnDemandBackupWorker
and PeriodicBackupWorker
畝OndemandBackupWorkerテスト
AndroidJUnit4
これは、単一のクラスのテストを駆動するものです.@RunWith(AndroidJUnit4::class)
class OnDemandBackupWorkerTest {
private lateinit var context: Context
private lateinit var executor: Executor
@Before
fun setUp() {
context = ApplicationProvider.getApplicationContext()
executor = Executors.newSingleThreadExecutor()
}
@Test
fun testOnDemandBackupWorker() {
val worker = TestListenableWorkerBuilder<OnDemandBackupWorker> (context).build()
runBlocking {
val result = worker.doWork()
assertTrue(result is ListenableWorker.Result.Success)
}
}
}
setUp
と単一のテストを書くtestOnDemandBackupWorker
畝TestListenableWorkerBuilder
これは基本的にListenableWorker
テストに使用します.doWork
内部runBlocking , (テスト用にメインスレッドに同期してテストを実行します).定期的なバックアップテスト
setUp
メソッドと書き込み// TEST 1
@Test
fun testPeriodicBackUpWorker() {
val worker = TestWorkerBuilder<PeriodicBackupWorker>(
context = context,
executor = executor
).build()
val result = worker.doWork()
assertTrue(result is ListenableWorker.Result.Success)
}
TestWorkerBuilder
これは基本的にWorker
テストに使用します.doWork
そして、Result.success
畝ENQUEUED
// TEST 2
@Test
fun testIfPeriodicBackupRunning() {
WorkManagerTestInitHelper.initializeTestWorkManager(context)
val testDriver = WorkManagerTestInitHelper.getTestDriver(context)
val workManager = WorkManager.getInstance(context)
val constraints = Constraints.Builder()
.setRequiresStorageNotLow(true)
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
val request =
PeriodicWorkRequestBuilder<PeriodicBackupWorker> (repeatInterval=24, TimeUnit.HOURS)
.setConstraints(constraints)
.build()
workManager.enqueue(request).result.get()
with(testDriver) {
this?.setPeriodDelayMet(request.id)
this?.setAllConstraintsMet(request.id)
}
val workInfo = workManager.getWorkInfoById(request.id).get()
assertEquals(workInfo.state, WorkInfo.State.ENQUEUED)
}
WorkManagerTestInitHelper
初期化に役立つWorkManager
テストのために.testDriver
ステータスがそうであるならば、制約を満たして、アサートするためにENQUEUED
PeriodicBackupWorkerTest
Source code. 助けてくれたなら、
Reference
この問題について(Androidでワークマネージャを使う), 我々は、より多くの情報をここで見つけました https://dev.to/aseemwangoo/using-workmanager-in-android-4337テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol