我的应用程序通过web服务调用与远程数据库同步数据。我在IntentService中进行这些调用,以便它们可以在后台运行(我称之为SyncService)。
启动my IntentService的代码如下所示:
Intent intent = new Intent();
intent.setClass(appContext, SyncService.class);
// place additional values in intent
intent.putExtra("data_type", SyncService.ITEM_TRACKING);
intent.putExtra("user_id", intUserId);
// call SyncService
appContext.startService(intent);
通常情况下,这个看起来很棒。然而,我的一个朋友,也是我的应用程序的用户,经常告诉我他的数据不同步并显示在我们的网站上。我在的时候,他的设备碰巧出现了症状。我把他的设备插入我的电脑,我发现:
有人知道问题出在哪里吗?你认为这是我的应用程序的问题吗?用Android?
我再次向Android发送了一条消息:“启动此IntentService或将消息发送到已经运行的IntentService。”在那一点上,我无法控制。这条消息永远不会传到IntentService。一旦我强制退出应用程序,消息就会被发送到IntentService,它就会完成它的工作。
更新:我认为这段代码很好,但我会把它贴出来,因为你们很多人可能都想看。
进入IntentService的每一个意图都有一个额外的指示,指示对我进行的调用的“类型”(即:我是调用这个web服务还是那个web服务,等等)。当意向进入IntentService时,我会检查“类型”,如果队列中已经有该类型的意向,我会在其中添加一个名为“跳过”的额外内容,以便在到达时,我不执行搜索(基本上IntentService可以建立很多意图,当20秒前调用此web服务时调用此web服务是没有意义的)。它基本上可以保护应用程序免受对html" target="_blank">网站的垃圾邮件攻击。
重要的是要注意,这些代码无论如何都不会被命中(一旦问题开始发生)。在应用程序被终止之前,不会调用onStartCommand
@Override
public int onStartCommand (Intent intent, int flags, int startId) {
// here be dragons
// overriding this method and adding your own code is dangerous. i've wrapped
// my code in a try/catch because it is essential that the super method be called
// every time this method is entered. any errors in my code should not prevent this
// or the app will explode.
try {
if (flags == 0 && intent != null && intent.hasExtra("data_type")) {
Integer intDataType = intent.getExtras().getInt("data_type");
if (!mCurrentTypes.containsKey(intDataType)
|| !mCurrentTypes.get(intDataType)) {
mCurrentTypes.put(intDataType, true); // put this type in the list and move on
}
else {
intent.putExtra("skip", true); // mark this Intent to be skipped
}
}
}
catch (Exception e) {
// Log.e("Error onStartCommand", "error: " + e);
}
return super.onStartCommand(intent, flags, startId);
}
private void processIntent(Intent intent) {
// do stuff if no "skip" Extra
mCurrentTypes.put(intDataType, false);
}
在我看来,根据你的意图设置一组标志可能会解决这个问题。
Intent intent = new Intent();
intent.setClass(appContext, SyncService.class);
// This way
intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
您可以在一个新任务中使用上面的标志使您的服务以新的方式启动。
这个答案提出了一个在类似情况下对我有效的解决方案。它不会修复您当前的代码,但建议了另一个可能更简单(更容易调试)的选项:
>
将一个广播接收器
添加到您的呼叫活动
,该活动监听来自IntentService
的成功意图
。
在调用活动
时,包含何时启动IntentService
的逻辑(不要包含在IntentService中)。逻辑是:
startService()
,并在调用活动中设置一个标志,使其无法调用
在您的
IntentService
中,像这样编写onStartCommand()
:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
在您的
IntentService
中,当您接收、解析并存储web服务响应时,调用sendBroadcast()
,以获得自定义操作成功。
这个逻辑只是一个大纲,必须对来自Web服务的错误消息进行微调,这些错误消息必须从
IntentService
广播到监听活动
。
希望这有帮助。
肯定有什么东西可以让你的服务在朋友的设备上运行。如果是这样,则对该意向服务的所有后续调用都将排队,直到当前调用完成。如果它没有完成,那么你将得到你所拥有的:下一个服务将不会启动。
你应该仔细检查一下:
之后,如果你认为一切都是绿色的:只需记录该服务的功能,并使用一些错误报告机制,让它自动从你的朋友设备发送。一个简单的解决方案可以是使用bugsense或等效工具。
接下来,设置某种看门狗:一个线程将继续运行,直到服务停止(当服务停止时,您只需告诉线程停止)。线程将不得不在超过某个时间限制后停止您的服务。
这个看门狗线程可以放在服务本身内部,也可以放在服务外部,尽管这可能更复杂。
13.4.IntentService 我们已对系统服务的工作方式有所了解,接下来可以利用系统服务的有关特性,简化UpdaterService的实现。回忆下前面的内容:UpdaterService会一直运行,定期从服务端抓取Timeline的更新。由于Service默认与UI在同一个线程(或者说,都在UI线程中执行)中执行,为避免网络操作造成界面的响应不灵,我们需要新建一个Updater线程,并将U
一、 定义 IntentService是Android里面的一个封装类,继承自四大组件之一的Service。 二、作用 处理异步请求,实现多线程。 三、 工作流程 注意:若启动IntentService多次,那么每个耗时操作则以队列的方式在IntentService的onHandleIntent回调方法中依次执行,执行完自动结束。 四、实现步骤 步骤1:定义IntentService的子类:传入线
由于Android Oreo后台执行限制,文档建议将重构为。 立即作为Oreo下面的运行,但在Oreo+上调度作业 https://developer.android.com/reference/android/support/v4/app/jobintentservice 在什么情况下,将正常的作为前台运行并带有持久通知是有意义的,何时更好? 我可以在中看到一个缺点是它不能立即启动。
我试图发送一个意图,从一个活动中的创建启动一个意图服务。但是,IntentService的onHandleIntent永远不会被接收。我尝试过用意图过滤器改变清单,但似乎没有任何效果。没有抛出异常,但是根本没有调用IntentService。 这是onCreate 这是IntentService类的创建者和OnHandleContent,我知道它不会被调用,因为logcat从不显示“检索到的意图”
我正在尝试为muzei创建一个艺术源(插件)。 该应用程序应该提供一个新的艺术源,在我的情况下,它是我的应用程序私人空间的文件夹。 按照muzei api中的示例及其提供的详细信息,我为我的应用程序创建了一个文件提供程序。 我已将此代码添加到我的清单: 我在我的res/xml文件夹中创建了xml文件: 如您所见,它指向我的文件夹。 最后一个是我的类,它扩展了: 在我看来,这是返回简单文件(名为wa
我有一个稍微令人困惑的问题,我认为由于一个愚蠢的疏忽,这将是一个容易解决的问题。 我的主要任务是上传图像和录音文件到我的服务器上的一个位置。我通过FTP这样做。 活动通过startService(intentName)调用服务 onHandleIntent()创建一个新线程 在新线程中,需要上传的文件被放入一个列表数组 在列表数组中循环。在这个循环中,将文件名传递给FTP服务器。如果添加成功,我会