可以快速连续多次启动意向服务会导致零附加吗?

时间:2014-02-04 02:06:18

标签: android android-intent

我们看到一个问题,我们的一个意向服务意外地为我们的一些用户检索了null字符串。我们无法重现这一点,并且我们不知道受影响用户的设备上是否随机或一致。受影响的用户与设备类型或Android版本之间似乎没有相关性。

我正在扩展IntentService并实施handleIntent方法,如下所示:

@Override
public void handleIntent(Intent intent) {
    String action = intent.getAction();

    if (action.Equals(ACTION_MARK_UNREAD)) {
        String messageKey = intent.getStringExtra(EXTRA_MESSAGE_KEY);

        // messageKey is null for some users
    }
}

使用字段:

public static final String ACTION_MARK_UNREAD = "com.myapp.action.MARK_UNREAD";
public static final String EXTRA_MESSAGE_KEY = "extraMessageKey";

在片段中,我们连续6次启动此服务:

    for (int i = 0; i < 6; i++) {
            Intent i = new Intent(MyIntentService.ACTION_MARK_UNREAD);
            i = i.setClass(mContext, MyIntentService.class);
            i.putExtra(MyIntentService.EXTRA_MESSAGE_KEY, i.toString());
            mContext.startService(i);
    }

为什么服务会为null额外提取messageKey的任何想法?

我们在应用程序中有其他区域启动此相同的服务,当发生这种情况时,我们无法确定它来自哪个区域。但是,通过查看日志,它似乎来自我提到的这个片段。日志显示null发生时的客户端时间戳是上一次发生后的几秒钟。这可能是因为服务队列移动缓慢,或者我的假设可能是错误的。

2 个答案:

答案 0 :(得分:2)

我的第一个猜测是很多其他人评论过的编译器问题,我在你的例子中发现了一些其他错误,例如Equals上面的 E

但是考虑到你的代码只是一个例子,我测试了很多这种方法,我得出的第一件事就是无论你的电话是Fragment还是Activity都归因于{{1} } Context与父Fragment相同。

阅读我们可以阅读的Activity文档:

  

所有请求都在一个工作线程上处理 - 它们可以作为   只要有必要(并且不会阻止应用程序的主循环),   但一次只能处理一个请求。

此处:http://developer.android.com/reference/android/app/IntentService.html

因此,我们可以得出结论,您的所有X请求将被逐个排队。

关于IntentService的Android文档的另一部分我们可以读到:

  

因为大多数已启动的服务不需要处理多个请求   同时(实际上可能是一个危险的多线程   方案),如果你使用。实现你的服务,它可能是最好的   IntentService类。

此处:http://developer.android.com/guide/components/services.html#ExtendingIntentService

因此,通过这些信息,您可以考虑IntentService是否是您需要的方法。正确?

在这里,您可以了解如何扩展IntentServicehttp://developer.android.com/guide/components/services.html#ExtendingService

完成,下面我粘贴了我为测试你的方法所做的代码。

ServiceActivity

MainActivity

public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for (int i = 0; i < 10; i++) { Intent intent = new Intent(MyIntentService.MY_ACTION); intent.setClass(this, MyIntentService.class); intent.putExtra(MyIntentService.EXTRA, UUID.randomUUID().toString()); startService(intent); } } } IntentService

MyIntentService

输出public class MyIntentService extends IntentService { public static final String MY_ACTION = "my.app.namespace.action.myaction"; public static final String EXTRA = "my_extra"; public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); if (action.equals(MY_ACTION)) { String messageKey = intent.getStringExtra(EXTRA); Log.i(EXTRA, messageKey); } } }

Log

答案 1 :(得分:1)

你会试试吗?

for (int y = 0; y < 6; y++) {
        Intent i = new Intent(MyIntentService.ACTION_MARK_UNREAD);
        i = i.setClass(mContext, MyIntentService.class);
        i.putExtra(MyIntentService.EXTRA_MESSAGE_KEY, y.toString());
        mContext.startService(i);
}

可能是编译器问题......