关于IntentService的清晰度

时间:2014-07-12 22:37:43

标签: android android-service android-preferences intentservice

我有这个扩展IntentService的服务。

public class RefreshService extends IntentService {

static final String TAG = "RefreshService";

public RefreshService() {
    super(TAG);
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreated");
}



@Override
public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroyed");
}

@Override
public IBinder onBind(Intent intent) {
    return  null;
}

@Override
protected void onHandleIntent(Intent intent) {

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final String username = prefs.getString("username", "").trim();
    final String password = prefs.getString("password", "").trim();

    Log.d(TAG, "onDestroyeds");

    if (TextUtils.isEmpty(username) || (TextUtils.isEmpty(password))){
        Toast.makeText(this, "Please update your username and password", Toast.LENGTH_LONG ).show();
        return;
    }

   // here code for fetching data and inserting into db.

}

}

如果缺少设置,而不是显示toast消息,则会出现以下错误。

 07-12 18:28:33.125    2961-2961/com.example.krishna.yamba I/menu_item_selected﹕ [0,Refresh]
07-12 18:28:33.143    2961-2961/com.example.krishna.yamba D/RefreshService﹕ onCreated
07-12 18:28:33.147    2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds
07-12 18:28:33.147    2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds
07-12 18:28:33.181    2961-2961/com.example.krishna.yamba D/RefreshService﹕ onDestroyed
07-12 18:28:33.197    2961-3637/com.example.krishna.yamba W/MessageQueue﹕ Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread
    java.lang.IllegalStateException: Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread
            at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
            at android.os.Handler.enqueueMessage(Handler.java:631)
            at android.os.Handler.sendMessageAtTime(Handler.java:600)
            at android.os.Handler.sendMessageDelayed(Handler.java:570)
            at android.os.Handler.post(Handler.java:326)
            at android.view.ViewRootImpl.loadSystemProperties(ViewRootImpl.java:5413)
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:378)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:253)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.widget.Toast$TN.handleShow(Toast.java:414)
            at android.widget.Toast$TN$1.run(Toast.java:322)
            at android.os.Handler.handleCallback(Handler.java:738)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.os.HandlerThread.run(HandlerThread.java:61)

我假设以下是真的

  1. onHandleIntent方法中的代码在不同的线程上运行。
  2. 因此在这里做一些密集的任务很好。 (在这种情况下,我只是获取和更新数据库)
  3. 当设置正确时,一切正常。然后把提取消息与提取和更新相比应该不是问题吗?

    如果设置为空白时如何发送Toast消息?

2 个答案:

答案 0 :(得分:3)

  

onHandleIntent方法中的代码在不同的线程上运行。

正确。

  

因此,在这里做一些密集的任务是很好的。 (在这种情况下,我只是获取和更新数据库)

正确。

  

然后把提取消息与提取和更新相比应该不是问题吗?

不,因为您无法从后台线程中引发Toast。实际上,这就是错误告诉你的。

  

如果设置为空白时如何发送Toast消息?

正确的答案是不使用Toast。这是告诉用户错误情况的第二差的解决方案(最糟糕的是根本不想告诉用户)。当Toast可读时,无法保证用户恰好在屏幕上看了一眼,因此用户可能会错过该消息。使用crouton或其他内容。

无论如何,你需要安排让主应用程序线程以某种方式更新UI ...如果你的UI碰巧在前台。这样做的现代解决方案通常涉及某种事件总线。目前有三种主要的事件总线实现:

我链接到的示例应用程序都演示了UI或 - Notification模式,如果我们碰巧在前台,我们会更新用户界面,或者我们提出Notification让我们如果我们没有前景中的UI,用户就会知道该事件。

答案 1 :(得分:2)

IntentService在单独的线程上执行 onHandleIntent 。另一方面,Toast在主/ UI线程上运行。要在Toast中显示IntentService,您需要执行以下操作:

new Handler(Looper.getMainLooper()).post(new Runnable() {           
    @Override
    public void run() {
        Toast.makeText(RefreshService.this, "Toast msg here", Toast.LENGTH_LONG).show();
    }
});