IntentService没有解雇

And*_*rew 6 service android intentservice

我的应用程序通过Web服务调用与远程数据库同步数据.我在IntentService中进行这些调用,以便它们可以在后台运行(我称之为SyncService).

启动我的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);
Run Code Online (Sandbox Code Playgroud)

这通常看起来很棒.但是,我的一位朋友,也是我的应用程序的用户,经常告诉我他的数据不会同步并显示在我们的网站上.当我在附近的时候,他的装置正好显示出症状.我将他的设备插入我的电脑,这是我发现的:

  • 启动SyncService的代码(即:上面的代码)被点击了.
  • 我在IntentService的onHandleIntent方法中有一个断点,它永远不会被击中.
  • 我检查了他的设备的运行服务列表,并且SyncService在那里运行.有趣的是,它已经运行了大约20分钟.我的印象是当IntentService完全没有进行Intent处理时就会自杀.
  • 我强制停止了SyncService(不是应用程序),突然之间,onHandleIntent开始被反复击中.就好像所有Intents都在设备上的某个地方排队,现在刚刚被SyncService抛出.

有没有人对可能出现的问题有任何想法?你认为这是我的应用程序的问题吗?用Android?

我再次向Android发送消息说"启动此IntentService或将消息发送到已经运行的IntentService".那时,我无法控制.消息永远不会到达IntentService.一旦我强制退出应用程序,消息就会被发送到IntentService并完成它的工作.

更新:我认为这段代码很好,但我会把它放好,因为很多人可能想看到它.

自带到IntentService每个意图有一个额外的电话,表示"类型"是什么,我做(即:我称这个 Web服务或者网络服务等).当一个Intent进入IntentService时,我检查"type",如果该类型的队列中已经存在一个Intent,我向它添加一个名为"skip"的Extra,这样,当它到达时,我不会牛逼执行搜索(基本IntentService可以建立大量的意图和它没有任何意义调用这个 Web服务时 Web服务在20秒前的称呼).它基本上保护应用程序免受垃圾邮件网站的侵害.

重要的是要注意,无论如何都不会触及此代码(一旦问题开始发生).在应用程序被终止之前,不会调用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);
    }
Run Code Online (Sandbox Code Playgroud)

Sni*_*las 4

肯定有某种东西可以让您的服务在您朋友的设备上运行。如果是这样,对此意向服务的所有后续调用都会排队,直到当前调用完成。如果它没有完成,那么您将得到您所拥有的:下一个服务将不会启动。

您应该仔细检查:

  • 您为网络操作提供适当的超时
  • 您为网络连接操作提供适当的超时
  • 线程之间不存在竞争条件。
  • 您记录服务内部可能发生的任何异常,您不想丢失此类信息。

之后,如果您认为一切都是绿色的:只需记录该服务的功能并使用一些错误报告机制将其从您朋友的设备自动发送即可。一个简单的解决方案可能是使用 bugsense 或等效方法。

接下来,放置某种看门狗:一个将继续运行直到您的服务停止的线程(您只需告诉您的线程在服务停止时停止)。经过一段时间限制后,线程将不得不停止您的服务。

该看门狗线程可以放置在服务本身内部或外部,尽管放置起来可能更复杂。