如何在后台线程中显示Toast消息

16

考虑以下代码。在Service.onStart()方法中,我创建并启动了一个线程,它应该显示Toast消息,但不起作用!

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();
            }
}

这对您也应该有效 https://dev59.com/7G025IYBdhLWcg3wOzTY - eyespyus
7个回答

28

在主/UI线程中执行UI操作。尝试这样做:

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

handler.post(new Runnable() {

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

9

我已经写好了一个类,用于在后台进程中显示 Toasts。可以在任何地方使用,例如在 AsyncTask 中。你只需要像这样创建这个类的实例:

ToastHandler mToastHandler = new ToastHandler(yourContext);

然后像使用makeToast()一样,用你的文本或资源id和Toast的持续时间来调用showToast()

以下是代码或直接下载链接链接:

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);
    }
}

"thread.interrupt()"和"thread = null"在runRunnable()中的作用是什么?将线程设置为null是多余的,因为该变量在函数返回时就消失了。 - Clyde
我不是线程专家。我只是想避免可能出现的问题或副作用。;-) - kaolick

1

0

我们使用handler来实现这个目的,因为它很容易实现... :)

步骤:

  1. 在主activity(onCreate)中声明一个handler
  2. 创建一个参数化构造函数,在后台运行的类中。接受上下文为参数。
  3. 现在从主activity创建一个线程并传递该活动的上下文。
  4. 现在从另一个线程(无论您想要发送的线程)向handler进行发布
  5. 现在在Toast中使用此上下文,而不是使用getApplicationContext()。

它运行良好。

mhandler.post(new Runnable() {
    public void run() {
        Toast.makeText(context,"Run ends",Toast.LENGTH_LONG).show();
    }
});

0

你不能在不是活动UI线程的线程上显示Toast。
如果你想在其他地方运行它,你只能使用runOnUiThread方法,这样它就会在UI线程上运行。

看看这个问题
Android: Toast in a thread


0

this替换为getBaseContext()


0

将单词this替换为getApplicationContext(),然后消息将出现。

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

正确的:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接