16

Consider the following code. In Service.onStart() method i have created and started a thread that should show Toast message but it is not working!

public class MyService extends Service{

    private static final String TAG = "MyService";  
    @Override
    public IBinder onBind(Intent intent)
    {
        return null;    
    }       

    @Override   
    public void onCreate()
    {   
    Toast.makeText(this, "My Service Created", Toast.LENGTH_SHORT).show();
         }  
    @Override
    public void onDestroy() 
    {   
    Toast.makeText(this, "My Service Stopped", Toast.LENGTH_SHORT).show();  
    }   
    @Override
    public void onStart(Intent intent, int startid)
    {
      Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
      DBIteratorThread dbThread=new DBIteratorThread();
      dbThread.myService=this;
      Thread t1 = new Thread(dbThread);
           t1.start();
    }

}
class DBIteratorThread  implements Runnable
{

    MyService myService;

    public void run()
    {
    //  Toast.makeText(myService, "Thread is Running", Toast.LENGTH_SHORT).show();
            }
}
Asif Rafiq
  • 281
  • 2
  • 4
  • 11
  • This should work for you also http://stackoverflow.com/questions/6134013/android-how-can-i-show-a-toast-from-a-thread-running-in-a-remote-service – eyespyus Sep 11 '11 at 14:51

7 Answers7

28

Do UI stuffs in main/UI thread. Try this:

Handler handler = new Handler(Looper.getMainLooper());

handler.post(new Runnable() {

        @Override
        public void run() {
            //Your UI code here
        }
    });
9

I have written a class for showing Toasts from background processes. Can be used everywhere, e.g. in an AsyncTask. You only have to create an instance of this class like

ToastHandler mToastHandler = new ToastHandler(yourContext);

and then call showToast() with your text or resource id and the Toast's duration like you normally would with makeToast().

Here is the code or the direct download link:

import android.content.Context;
import android.os.Handler;
import android.widget.Toast;

/**
 * A class for showing a <code>Toast</code> from background processes using a
 * <code>Handler</code>.
 * 
 * @author kaolick
 */
public class ToastHandler
{
    // General attributes
    private Context mContext;
    private Handler mHandler;

    /**
     * Class constructor.
     * 
     * @param _context
     *            The <code>Context</code> for showing the <code>Toast</code>
     */
    public ToastHandler(Context _context)
    {
    this.mContext = _context;
    this.mHandler = new Handler();
    }

    /**
     * Runs the <code>Runnable</code> in a separate <code>Thread</code>.
     * 
     * @param _runnable
     *            The <code>Runnable</code> containing the <code>Toast</code>
     */
    private void runRunnable(final Runnable _runnable)
    {
    Thread thread = new Thread()
    {
        public void run()
        {
        mHandler.post(_runnable);
        }
    };

    thread.start();
    thread.interrupt();
    thread = null;
    }

    /**
     * Shows a <code>Toast</code> using a <code>Handler</code>. Can be used in
     * background processes.
     * 
     * @param _resID
     *            The resource id of the string resource to use. Can be
     *            formatted text.
     * @param _duration
     *            How long to display the message. Only use LENGTH_LONG or
     *            LENGTH_SHORT from <code>Toast</code>.
     */
    public void showToast(final int _resID, final int _duration)
    {
    final Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
        // Get the text for the given resource ID
        String text = mContext.getResources().getString(_resID);

        Toast.makeText(mContext, text, _duration).show();
        }
    };

    runRunnable(runnable);
    }

    /**
     * Shows a <code>Toast</code> using a <code>Handler</code>. Can be used in
     * background processes.
     * 
     * @param _text
     *            The text to show. Can be formatted text.
     * @param _duration
     *            How long to display the message. Only use LENGTH_LONG or
     *            LENGTH_SHORT from <code>Toast</code>.
     */
    public void showToast(final CharSequence _text, final int _duration)
    {
    final Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
        Toast.makeText(mContext, _text, _duration).show();
        }
    };

    runRunnable(runnable);
    }
}
kaolick
  • 4,817
  • 5
  • 42
  • 53
  • What is the purpose of "thread.interrupt()" and "thread = null" in runRunnable()? Setting thread to null is redundant since that variable disappears when the function returns anyway. – Clyde Aug 22 '13 at 02:41
  • I'm no `thread` expert. I just wanted to avoid possible problems or side effects. ;-) – kaolick Aug 25 '13 at 14:21
1

You should be able to use the getApplicationContext() method to get the context with which to show the Toast.

See getApplication() vs. getApplicationContext() for some nice discussion on this.

Community
  • 1
  • 1
RandomSort
  • 600
  • 7
  • 22
0

You can't show a Toast on a thread that is not the activity's ui thread.
you can only run it somewhere else if you use runOnUiThread method so that it runs on the ui thread

Look at this question
Android: Toast in a thread

Community
  • 1
  • 1
chrmcpn
  • 574
  • 6
  • 10
0

We use handler for this purpose because it is easy... :)

Steps:

  1. declare a handler in the main activity (onCreate)
  2. a class which is to be run in the background in that create a parameterized constructor . Taking the Context a perimeter .
  3. now create a thread from the main activity and pass the Context of that activity.
  4. now Post to the handler from that another thread (from whichever thread u want to send)
  5. now use this context in the Toast, instead of using getApplicationContext()

It runs well.

mhandler.post(new Runnable() {
    public void run() {
        Toast.makeText(context,"Run ends",Toast.LENGTH_LONG).show();
    }
});
sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
Raj Kumar
  • 300
  • 3
  • 8
0

replace word this with getApplicationContext() The message will then appear

Toast.makeText(this, "My Service Created", Toast.LENGTH_SHORT).show();

the correct :

Toast.makeText(getApplicationContext(), "My Service Created", Toast.LENGTH_SHORT).show();
0

Substitute this with getBaseContext().

Ricky
  • 7,785
  • 2
  • 34
  • 46
Ian Low
  • 399
  • 4
  • 14