当在后台运行的doWork()a 方法中执行任务时(例如,使用 定期在后台运行的工作程序),我是否应该显示正在进行的通知?如果是这样,我该怎么办?假设我有类似的东西:WorkerPeriodicWorkRequest
class NoticeWorker(context: Context, params: WorkerParameters)
: Worker(context, params) {
override fun doWork(): Result {
// do some work here
return Result.SUCCESS
}
}
Run Code Online (Sandbox Code Playgroud)
然后执行
WorkManager.getInstance().enque(workerObj)
Run Code Online (Sandbox Code Playgroud) 尝试将视频压缩放在后台,但应用程序被杀死WorkManager并被JobSchedular摧毁
如何解决这个问题?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ComponentName componentName = new ComponentName(ConcatVideoActivity.this, ConcatVideoJobServiceRepository.class);
JobInfo jobInfo;
PersistableBundle bundle = new PersistableBundle();
bundle.putString(FIRST_IMG, doctorCredentialModel.getDoctorFrontimg().replaceAll(" ", "%20"));
bundle.putString(LAST_IMG, doctorCredentialModel.getDoctorBackimg().replaceAll(" ", "%20"));
bundle.putString(VIDEO_URL, doctorCredentialModel.getVidUrl());
if(doctorCredentialModel.getDoctorName()!=null){
bundle.putString(DR_NAME, doctorCredentialModel.getDoctorName());
}else{
bundle.putString(DR_NAME,getString(R.string.app_name));
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
jobInfo = new JobInfo.Builder(12, componentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setExtras(bundle)
.build();
} else {
jobInfo = new JobInfo.Builder(12, componentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setExtras(bundle)
.build();
}
try {
JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
int resultCode = jobScheduler.schedule(jobInfo);
if (resultCode …Run Code Online (Sandbox Code Playgroud) 我正在使用新的 WorkManager,并且想知道,当我安排定期工作时,如何避免重新安排它,它是否由操作系统自动处理?
使用WorkManager 2.1.0,
如何在不使用 WorkContinuation 的情况下对一组操作进行排队?如果我有
val firstSet = firstWorkers()
val secondSet = secondWorkers()
Run Code Online (Sandbox Code Playgroud)
完成secondSet后如何执行?firstSet
我不想链接工作,因为secondSet即使调用失败,我仍然希望执行firstSet
我尝试过的事情,
排队
workManager.enqueue(firstSet)
workManager.enqueue(secondSet)
Run Code Online (Sandbox Code Playgroud)
我假设该enqueue函数会导致操作按顺序运行,但是它们运行无序,我假设这是由于多线程造成的?
实时数据
workManager.enqueue().state().observe {}workManager.enqueue(secondSet)并在之后运行SUCCESS
异步/等待
coroutineScope.async { workManager.enqueue().await() }
即使结果是按顺序返回的,网络调用仍然会发生乱序,在某些情况下firstSet直到最后才执行。
我能找到的唯一“解决方案”Result.success()是从函数返回 a,doWork()即使它失败了,这似乎是错误的。
即使先前的调用之一失败,如何才能顺序执行操作?
我正在对未来的工作进行排队,同时还“现在”运行初始工作。20 个项目加入队列后,添加的任何新项目都不再立即运行,我将不得不等待 30 天才能查看它们是否运行;)
将工作项的初始延迟设置为 10 秒(允许的最小值)后,我已经等待了 24 小时以上。
如果我安排第 21 份工作,什么也不会发生。取消 10 秒后运行的前 20 个和第 21 个作业中的任何一个。100% 可重复——重新安排作业 20,没什么。取消作业 21,作业 20 将在 10 秒后运行。
dependencies {
implementation 'androidx.work:work-runtime:2.3.4'
}
fun scheduleTickle(context: Context, item: Item) {
// item.id is the auto-generated primary key from the database
val periodicWorkRequest = PeriodicWorkRequest.Builder(
MessageWorker::class.java,
item.minimumInterval,
TimeUnit.DAYS
).let {
it.setInputData(
Data.Builder()
.putLong("EXTRA_KEY_ITEM_ID", item.id)
.build()
)
it.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
it.addTag("com.example.myapp.periodicWork.${item.id}")
it.setInitialDelay(10, TimeUnit.SECONDS)
}.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
item.id.toString(),
ExistingPeriodicWorkPolicy.REPLACE,
periodicWorkRequest
)
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试测试一个简单的CoroutineWorker使用AndroidJUnit4,如官方文档
提到的
我的测试和错误:
package com.shalaga44.workmanager
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.work.testing.TestListenableWorkerBuilder
import kotlinx.coroutines.runBlocking
import org.hamcrest.Matchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SleepWorkerTest {
private lateinit var context: Context
@Before
fun setUp() {
context = ApplicationProvider.getApplicationContext() }
@Test
fun testSleepWorker() {
val worker = TestListenableWorkerBuilder<SleepWorker>(context).build()
runBlocking {
val result = worker.doWork()
assertThat(result, `is`(Result.success())) //The Error here
//Type inference failed. Please try to specify type arguments explicitly.
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的工人: …
junit unit-testing kotlin android-architecture-components android-workmanager
我刚刚开发了一个 Android 应用程序(minSdkVersion 23/targetSdkVersion 29),它可以连接到 BluetoothLE 设备以定期获取数据。
现在,在 MainActivity(不是第一个活动)中,我执行以下注册广播接收器:
public class StatusActivity extends AppCompatActivity {
BleService mBleService;
BleScanCallback mScanCallback;
BroadcastReceiver mBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
mBroadcastReceiver = new LibBleBroadcastReceiver(this);
IntentFilter intentFilter = new IntentFilter()
intentFilter.addAction(BleService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BleService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BleService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BleService.ACTION_DATA_AVAILABLE);
intentFilter.addAction(BleService.ACTION_DID_WRITE_CHARACTERISTIC);
intentFilter.addAction(BleService.ACTION_DID_FAIL);
registerReceiver(mBroadcastReceiver, intentFilter);
mScanCallback = new LibBleScanCallback(this);
intent = new Intent(this, BleService.class);
connection = new LibBleServiceConnection(this);
startService(intent);
if (!bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
throw new IllegalStateException("bindService not successful");
}
}
...
public void onDeviceDiscovered(String device_address){
device_connected.activateNotifications(mBleService, connected_device);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() { …Run Code Online (Sandbox Code Playgroud) android background-process android-bluetooth android-jobscheduler android-workmanager
我有一个扩展 FirebaseMessagingService 的类,其中在 onMessageRecieve() 方法中我使用工作管理器安排工作。在工作类中,我想将 Firebase Id 令牌发布到我的服务器(我正在使用同步齐射请求),但对于 Firebase IdToken,我在工作类中使用 Tasks.await() 但 logcat 显示以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.calendarapp, PID: 29746
java.lang.IllegalStateException: Must not be called on the main application thread
at com.google.android.gms.common.internal.Preconditions.checkNotMainThread(com.google.android.gms:play-services-basement@@17.1.1:51)
at com.google.android.gms.common.internal.Preconditions.checkNotMainThread(com.google.android.gms:play-services-basement@@17.1.1:48)
at com.google.android.gms.tasks.Tasks.await(Unknown Source:16)
at com.example.calendarapp.MyWorker$1.onComplete(MyWorker.java:130)
at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Run Code Online (Sandbox Code Playgroud)
Firebase消息服务
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
FirebaseAuth mAuth;
@Override
public void onMessageReceived(@NonNull RemoteMessage …Run Code Online (Sandbox Code Playgroud) multithreading android firebase firebase-cloud-messaging android-workmanager
由于最近对后台服务和隐式广播的限制,Android开发人员只能使用JobScheduler以及更高级别的WorkManager来安排后台任务。
WorkManager的Worker类非常简单,但是我对实现正在进行的工作而不是一次性工作的最佳方法有些困惑。在我们的示例中,让我们考虑蓝牙低功耗扫描,但是同样的顾虑也适用于所有正在进行的不确定的工作。
这样的事情显然是行不通的:
public class MyWorker extends Worker {
private BluetoothLeScanner mBluetoothLeScanner;
@Override
public Worker.Result doWork() {
mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
// Pretend there's some bluetooth setup here
// ...
mBluetoothLeScanner.startScan( .. , .. , .. );
return Result.SUCCESS;
}
}
Run Code Online (Sandbox Code Playgroud)
上面我们开始扫描,然后立即超出范围,因此扫描将不会继续。
我们可以使用wait()/ notify()解决这个问题,但是感觉很脏。像这样
public class MyWorker extends Worker {
private BluetoothLeScanner mBluetoothLeScanner;
private final Object mLock = new Object();
private Handler mBackgroundHandler;
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread …Run Code Online (Sandbox Code Playgroud) android background bluetooth bluetooth-lowenergy android-workmanager
我已安排工作经理定期在特定时间执行任务。但它正在与其他Android版本一起使用,例如25或更低版本。当我在API 28上运行它时,如果我从最近的列表中清除应用程序,它将停止触发广播。
我在活动中安排了这样的工作经理:
OneTimeWorkRequest mywork = new OneTimeWorkRequest.Builder(MyWorker.class).setInitialDelay(15, TimeUnit.SECONDS).build();
WorkManager.getInstance().enqueue(mywork);
Run Code Online (Sandbox Code Playgroud)
这是我的工人班:
public class MyWorker extends Worker {
@NonNull
@Override
public Worker.WorkerResult doWork() {
// Do the work here
Mylogger.getInstance().printLog("MyWorr","doWork()");
//fire broadcast from here
Intent broadcastIntent = new Intent(getApplicationContext(), TimeMatchingBroadcastReceiver.class);
getApplicationContext().sendBroadcast(broadcastIntent);
CommonUtils.scheduleWorkManager();
// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}
Run Code Online (Sandbox Code Playgroud)
即使关闭或清除所有版本的android上的最新应用程序,我也要执行工作管理器。谢谢。
android android-service android-lifecycle android-jetpack android-workmanager
android ×9
kotlin ×2
android-architecture-components ×1
background ×1
bluetooth ×1
firebase ×1
java ×1
junit ×1
unit-testing ×1