Search code examples
androidandroid-serviceandroid-preferencesintentservice

Clarity on IntentService


I have this service which extends 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.

}

}

When the settings are missing, instead of a toast message being show, I get the following error.

 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)

I'm assuming the following are true

  1. The code in onHandleIntent method is run on different thread.
  2. Therefore it is fine to do some intensive tasks here. (in this case I'm just fetching and updating db)

When the settings are correct everything works fine. Then putting a toast message compared to fetching and updating should not be a problem right?

How to put a toast message when the settings are blank?


Solution

  • IntentService executes its onHandleIntent on a separate thread. On the other hand, Toast runs on main/UI thread. In order to show Toast in IntentService, you need to do something like this:

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