我最近将所有服务替换为前台服务和JobIntentService,因为在oreo及以上版本中存在一些后台执行限制(https://developer.android.com/about/versions/oreo/background) . 根据文档,JobIntentService的行为类似于Android 7及以下版本的Intent Service,其作用类似于Android 8及以上版本的JobScheduler . 我注意到Google提供的新JobIntentService存在问题 .
Android 8 & above:
在Android 8及更高版本中连续发生崩溃 . 这里有一张票提到了同样的问题https://issuetracker.google.com/issues/63622293并且我添加了一些极客建议的临时解决方案 .
Android 7 & below: 一旦工作完成,JobIntentService就像Intent Service一样不会停止 .
我在服务中实现了JobIntentService,只要用户执行某些操作就会触发该服务 .
Code
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();
}
}
}
}
3 回答
我已经在阅读谷歌文档中已经失去了2年......这些是
use-less
...有no proper documentation
和no proper sample codes for its developers
.. !!所以我在stack-overflow
的每个帖子中都提到了这一点,因为它有助于节省其他人的时间.. !!它看起来你是一个优秀的程序员;只需要一些
hints to your posted question
:Hint-1 :
foreground service :
如果你需要
ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
,它将在服务中使用,它从OnStartCommand
返回START_STICKY
. 再次不建议使用,好像你想不惜一切代价实现它......那么你将不得不使用setOngoing(true)
的通知,哪个最终用户无法刷掉你的通知,它将永远保留在那里.. ..Use of the foreground service :
接收器也有限制;在
Oreo
之后,您不能通过在清单中声明它并仅通过制作接收器来使用所有接收器和意图动作...我建议只使用BootComplete
权限并使用单个receiver
接收boot_completed
意图并调用service
如果在O之下并调用O之上的前台服务 . 现在从该前台服务中为所有人实现运行时接收器并在Ondestroy方法中取消注册它 . 我从来没有找到实现运行时接收器的官方示例代码,最后我已经成功实施了几个月的艰苦工作......是的,因为谷歌不是一个聪明的工作When to use foreground service :
只有你想实现广播接收器....如果你不想实现任何广播接收器;远离.......
Hint-2 :
服务质量:
只做一个非常微小的工作......然后退出...它必须由S
topSelf()
退出...再次,Services can cause data-loss
如果被多次调用...同样的服务线程可以运行多次...再次如果你想要一项服务做很多工作...使用START_STICKY
...但是再次不建议我已经建议,何时在提示1中使用它 .** Intentservice的质量如下:**
执行相对较长时间运行的任务并且
property of execution serially only
如果您反复调用相同的intentService
,则所有调用将保存在queue
中,并在完成one by one
后执行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
: -易于使用
使用简单的JobService
可以运行更长或更短的时间任务......
EVEN ALL THE TIME RUNNING TASK
EVEN SUPPORTED BY NON STANDARD COMPANIES
喜欢vivo,mi,oppo,one 3,...需要stock-android
对其进行更改并给出FunTouchO,ColorOs,Oxygen等名称只需将电池设置更改为"Do not optimise this app"
是谷歌正式支持它并建议使用它
It创建
GooglePlyService
的实例并在其中运行,显然也是非标准公司不会限制谷歌应用程序执行其任务 .适用于
Oreo
..,即使我已在Android P
上测试过它,并且在Android 5.0版本下作为AlarmManager
任务工作 .仍然我建议使用
minsdk above 16
,target sdk 26
,好像万一你要将你的应用程序上传到google play
它现在是强制性的,并且会听到你的消息 . 和compile sdk 26
.在清单中绑定您的
JobService
并使用receive_boot_complete
的单行权限只需安排它...它将在每个制造商的市场上的每台设备上启动......即使在
cold boot
和hot boot
它最大限度地减少了很多代码和
you can focus on actual tasks
.任务完成后,您可以
return false
指示任务已完成,它将结束JobService .为什么我的建议是因为我是一个很好的
UNKNOwn
公司,并且经历过foreground service
在各种类型的Android手机制造商中引起的问题......这不是Apple and ios
所以我们必须经历它 . 自18年以来一直是开发人员,我今天大部分都在编码...在所有开发项目中,我的开发策略仅由我来考虑 .我想你只需要这么多代码 . 创建一个新的类MyJobIntentService并编写这么多代码并调用postData()来启动您的服务 .
并确保在清单文件中添加您的服务
JobIntentService which acts like Intent Service is not getting stopped once the work is done
问题出在您的扩展类FixedJobIntentService dequeueWork方法中 .
尝试将其更改为如下所示
查看JobIntentSerivce代码,工作项处理器逻辑如下所示,即在队列中没有剩余工作项之前处理所有项目(即,为每个项目调用onHandleWork)
实现中的问题是在处理完第一个工作项之后,super.dequeueWork()返回null,你没有处理它,只是发送一个新的FixedGenericWorkItem对象传递空值 . 您可能会发现在后续调用中将空值传递给onHandleWork .
希望这有助于解决您的问题 .