【问题标题】:Using toast inside timertask在 timertask 中使用 toast
【发布时间】:2020-07-15 15:29:16
【问题描述】:

发现网上有人有类似问题here

这不起作用:

Timer t = new Timer(false);
t.schedule(new TimerTask() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "msg", Toast.LENGTH_LONG).show();
}
}, 5000);

但是如果我在 timertask 之外实例化 toast 然后在 run 中显示它,它就可以工作。

我觉得可能跟所谓的UI线程有关,

但究竟如何?

【问题讨论】:

  • 您不能使用 Toast 或从非 UI 线程进行任何 UI 更新。
  • @Eng.Fouad,还有更多细节吗?
  • 查看this page 的末尾,特别是上面写着:Make sure that you access the Android UI toolkit only on the UI thread.
  • @Eng.Fouad,我正在寻找更多内部原因

标签: android


【解决方案1】:

试试这个

Timer t = new Timer(false);
t.schedule(new TimerTask() {
@Override
public void run() {
       runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), "msg", Toast.LENGTH_LONG).show();
            }
        });

    }
}, 5000);

【讨论】:

  • 我知道有几种方法可以让它工作,但我只是不知道为什么原来的方法不起作用,以及为什么在外面创建 toast 会起作用。
  • 几乎完美,但您不应该将 ApplicationContext 用于 Toast,您应该使用 Activity。
【解决方案2】:

使用 Timer 启动一个新线程,我想该线程无权访问getApplicationContext。正确的做法是使用 Handler 并调用 Handler 的 postDelayed 方法 - 它不会启动新线程。

阅读:http://developer.android.com/resources/articles/timed-ui-updates.html

您发布的链接有一个工作示例,这是正确的做法:

final Context ctx = this;
Handler mHandler = new Handler();

Runnable
makeToast = new Runnable() {
    public void run() {
        Toast.makeText(ctx, "msg", Toast.LENGTH_LONG).show();
    }
};
mHandler.postDelayed(makeToast, 1000);

【讨论】:

  • 我也试过ActivityClassName.this,还是不行,为什么?
【解决方案3】:

每次启动应用程序时,它都会在 UI 线程(也称为主线程)上启动。

无论何时创建新线程、计时器或 AsyncTask,根据定义,它们都是在创建新线程。不是主线程的线程根本没有修改 UI 的权限。

【讨论】:

    【解决方案4】:

    在 UIThread 上使用 Toast。你可以通过Handler或者runOnUiThread

    【讨论】:

      猜你喜欢
      • 2012-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多