Question

This IntentService I created will show Toasts in onStartCommand() and in onDestroy(), but not in onHandleIntent(). Am I missing something about the limitations of an IntentService?

public class MyService extends IntentService {

private static final String TAG = "MyService";

public MyService(){
    super("MyService");
}

@Override
protected void onHandleIntent(Intent intent) {
    cycle();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); //This happens!
    return super.onStartCommand(intent,flags,startId);
}

@Override
public void onCreate() {
    super.onCreate();

}

@Override
public void onDestroy() {
    Toast.makeText(this, "service stopping", Toast.LENGTH_SHORT).show(); //This happens!
    super.onDestroy();
}

private void cycle(){
      Toast.makeText(this, "cycle done", Toast.LENGTH_SHORT).show();  //This DOESN'T happen!
      Log.d(TAG,"cycle completed"); //This happens!
}
}
Was it helpful?

Solution

onHandleIntent() is called from a background thread (that is what IntentService is all about), so you shouldn't do UI from there.

OTHER TIPS

The accepted answer is not correct.

Here is how you can show toast from onHandleIntent():

Create a DisplayToast class:

public class DisplayToast implements Runnable {
    private final Context mContext;
    String mText;

    public DisplayToast(Context mContext, String text){
        this.mContext = mContext;
        mText = text;
    }

    public void run(){
        Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
    }
}

Instantiate a Handler in your service's constructor and call the post method with a DisplayToast object inside.

public class MyService extends IntentService {
Handler mHandler;

public MyService(){
    super("MyService");
    mHandler = new Handler();
}

@Override
protected void onHandleIntent(Intent intent) {
    mHandler.post(new DisplayToast(this, "Hello World!"));

}
}

You should start the Toast on the main thread:

new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
        }
});

This is because otherwise the thread of the IntentService quits before the toast can be send out, causing a IllegalStateException:

java.lang.IllegalStateException: Handler (android.os.Handler) {12345678} sending message to a Handler on a dead thread

Another option is RxJava, e.g.:

private void showToast(final String text) {
    Observable.just(text)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
            }
        });
}

Caveat: I'm new to Android.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top