我最近将所有服务替换为前台服务和JobIntentService,因为在oreo及更高版本中存在一些后台执行限制(https://developer.android.com/about/versions/oreo/background)。根据文档,JobIntentService的行为类似于适用于Android 7及更高版本的Intent Service,行为类似于JobScheduler(适用于Android 8及更高版本)。我注意到Google提供的新JobIntentService中存在问题。
Android 8及更高版本:
在Android 8及更高版本中,崩溃持续发生。这里有一张票提到了同一问题https://issuetracker.google.com/issues/63622293,我添加了一些极客建议的临时修复程序。
Android 7及更低版本: 工作完成后,像Intent Service一样的JobIntentService不会停止。
我已在服务中实现JobIntentService,只要用户执行某些操作,该服务就会触发。
代码
public class SampleJobIntentService extends FixedJobIntentService {
public static void postData(Context context, String data) {
Intent intent = new Intent(context, SampleJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
SampleJobIntentService.enqueueWork(context,intent);
}
public static void enqueueWork(Context context, Intent work) {
SampleJobIntentService.enqueueWork(context, SampleJobIntentService.class, JOB_ID, work);
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else
Log.e("action not found for ");
}
}
}
为了避免JobIntentService崩溃,我从https://issuetracker.google.com/issues/63622293
中引用了一些参考文献public abstract class FixedJobIntentService extends JobIntentService {
@Override
GenericWorkItem dequeueWork() {
try {
return new FixedGenericWorkItem(super.dequeueWork());
} catch (SecurityException ignored) {
doStopCurrentWork();
}
return null;
}
private class FixedGenericWorkItem implements GenericWorkItem {
final GenericWorkItem mGenericWorkItem;
FixedGenericWorkItem(GenericWorkItem genericWorkItem) {
mGenericWorkItem = genericWorkItem;
}
@Override
public Intent getIntent() {
if (mGenericWorkItem != null) {
return mGenericWorkItem.getIntent();
}
return null;
}
@Override
public void complete() {
try {
if (mGenericWorkItem != null) {
mGenericWorkItem.complete();
}
} catch (IllegalArgumentException ignored) {
doStopCurrentWork();
}
}
}
}
答案 0 :(得分:6)
嗯...,这是一个很大的理论...!它不可能将所有内容都放在这里。我将尽我所能,这将使您的一些概念变得清晰。
我已经失去了整整2年的阅读google文档的时间... use-less
...用no proper documentation
和no proper sample codes for its developers
.. !!所以我在stack-overflow
的每篇文章中都提到了这一点,因为这将有助于节省其他人的时间。
看起来你是一个很好的程序员;只需要一些hints to your posted question
:
提示1:
您:-我最近将我的所有服务替换为前台服务,并且 JobIntentService
前台服务:
如果您需要ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
,则将其用于服务中,该服务将从其START_STICKY
返回OnStartCommand
。还是不建议您使用它,就像您想不惜一切代价实施它一样...然后您将不得不使用带有setOngoing(true)
的通知,该最终用户将无法清除您的通知,它将保留永远存在....
使用前台服务:
接收者也受到限制;从Oreo
开始,您不能通过在清单中声明它并仅通过使其成为接收者来使用所有接收者和意图操作...我建议仅使用BootComplete
许可并使用单个{{1 }}会收到receiver
的意图,如果在O之下,则调用boot_completed
,然后在O之上调用前景服务。现在,从该前景服务中,您将为所有对象实现运行时接收器,并在Ondestroy方法中取消注册。我从未找到用于实现运行时接收器的官方示例代码,但经过数月的艰苦努力,我终于成功实现了它。是的,由于google,这不是一个聪明的工作
何时使用前台服务:
仅当您想要实现广播接收器时。...如果您不想实现任何广播接收器;远离....
提示2:
您:-我最近将我的所有服务替换为前台服务,并且
service
**服务的质量为:**
只需做一个很小的工作...然后退出...它必须由S JobIntentService
退出...同样,如果多次调用topSelf()
...作为相同的服务线程可以运行不止一次...如果您想让服务执行大量工作,请再次使用... Services can cause data-loss
...但是不建议再次使用,我已经建议何时使用它在提示1中。
** Intentservice的质量为:**
做一个运行时间相对较长的任务,它有START_STICKY
,如果您一次又一次调用相同的property of execution serially only
,则所有调用都将保留在intentService
中,并将被执行{{ 1}}完成queue
之后。如上所述,服务中的情况并非如此。它本身就结束了...无需由开发人员结束。.
**所有产品的独特品质:**
一旦他们one by one
,Android便可以阻止他们在将来调用,而不会在崩溃时通知您。需要使用one by one
至crashed
来处理它们。再次...如果为try-catch-exception
,则为avoid crash
you are implementing threads within services
...
**然后是什么以及如何实施:**
使用try-catch-exception
:-
will not save your application from being crashing
FireBaseJobScedular
(例如vivo,mi,oppo,one + 3,...)需要EVEN ALL THE TIME RUNNING TASK
对其进行更改,并命名为FunTouchOs,ColorOs,OxygenOs EVEN SUPPORTED BY NON STANDARD COMPANIES
的实例并在其中运行,而且显然非标准公司也不会限制google应用执行其任务。stock-android
上工作..,即使我已经在GooglePlyService
上进行了测试,并且在Android 5.0以下版本中都可以作为Oreo
的任务来工作。Android P
,AlarmManager
,好像您要将应用程序上载到minsdk above 16
一样,现在是强制性的,而且早已听到您的消息。和target sdk 26
。google play
绑定到清单中并使用compile sdk 26
的单行权限JobService
和receive_boot_complete
上cold boot
。hot boot
表示任务已完成,它将结束JobService。为什么要提出建议,因为我you can focus on actual tasks
是一家return false
公司,并且在许多类型的android手机制造商中都经历过CTO
引起的问题...不是UNKNOwn
,所以我们不得不经历。自从过去18年以来一直保持开发人员的身份,我现在也主要编写代码...在所有开发项目中,其开发策略只由我自己考虑。
更正我...也...您没有提到
foreground service
,Apple and ios
与...有关,而您确实想要在what your tasks
...让我知道...,很荣幸能为您提供帮助。这是一个一般性的理论答案,而不是您想要的。...但是要给您实际的答案,我需要确切的项目范围。
答案 1 :(得分:0)
我认为您只需要这么多的代码。创建一个新的MyJobIntentService类,并编写大量代码,然后调用postData()启动服务。
public class MyJobIntentService extends JobIntentService {
public static void postData(Context context, String data) {
final Intent intent = new Intent(context, MyJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
enqueueWork(context, MyJobIntentService.class, 1000, intent);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Ln.d("Cancelled service");
super.onDestroy();
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
final SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else {
Log.e("action not found for ");
}
}
}
}
并确保将服务添加到清单文件中
<service
android:name="service.MyJobIntentService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
答案 2 :(得分:0)
工作完成后,不会像Intent Service一样工作的JobIntentService
问题出在您的扩展类FixedJobIntentService dequeueWork方法中。
尝试将其更改为以下内容
GenericWorkItem superValue = super.dequeueWork();
if (superValue != null) {
return new FixedGenericWorkItem(superValue);
}
return null;
查看JobIntentSerivce代码,下面是“工作项”处理器逻辑,即,直到队列中没有剩余工作项为止,所有项均已处理(即为每个项调用onHandleWork)
while ((work = dequeueWork()) != null) {
if (DEBUG) Log.d(TAG, "Processing next work: " + work);
onHandleWork(work.getIntent());
if (DEBUG) Log.d(TAG, "Completing work: " + work);
work.complete();
}
实现中的问题是在处理完第一个工作项之后,super.dequeueWork()返回null,您不必理会它,而只是发送一个传递null值的新FixedGenericWorkItem对象。您可能会发现在后续调用中将空值传递给onHandleWork。
希望这有助于解决您的问题。