android - ExceptionInInitializerError & 无法在未调用 Looper.prepare() 的线程内创建处理程序

标签 android handler toast

1.我想在一个线程中 toast

2.我已经设置了Looper.getMainLooper()

但是还是崩溃了 我知道可以使用 activity.runOnUiThread 解决这个问题 但我想找到另一种方法来解决,只需更改ToastUtil即可。

请,提前致谢

public class ToastUtil {

private static Toast toast = Toast.makeText(MainApplication.getApp(),"",Toast.LENGTH_SHORT);
private static Toast scrollToast = Toast.makeText(MainApplication.getApp(),"",Toast.LENGTH_SHORT);

public static void show(final String src) {
    if (StringUtils.isEmpty(src)) {
        return;
    }
    r.post(new Runnable() {
        @Override
        public void run() {
            toast.setText(src);
            toast.show();
        }
    });
    Logger.d("Toast", src);
}

public static void show(int resId) {
    final String src;
    src = MainApplication.getApp().getResources().getString(resId);
    if (StringUtils.isEmpty(src)) {
        return;
    }
    r.post(new Runnable() {
        @Override
        public void run() {
            toast.setText(src);
            toast.show();
        }
    });
}

public static void showScrollToast(final String src) {
    final View toastRoot = LayoutInflater.from(MainApplication.getApp()).inflate(R.layout.widget_view_toast, null);
    MyTextView textView = (MyTextView) toastRoot.findViewById(R.id.scroll_toast);
    textView.setText(src);
    r.post(new Runnable() {
        @Override
        public void run() {
            scrollToast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP, 0, DisplayMetricsTools.dp2px(50));
            scrollToast.setDuration(Toast.LENGTH_LONG);
            scrollToast.setView(toastRoot);
            scrollToast.show();
        }
    });

}

private static Handler r = new Handler(Looper.getMainLooper());}

崩溃日志:

 java.lang.ExceptionInInitializerError
                                                 at com.utils.ToastUtil.show(ToastUtil.java:24)
                                                 at com.utils.ErrorInfo.showError(ErrorInfo.java:43)
                                                 at com.integration.CreateBoardActivity.allotModerators(CreateBoardActivity.java:392)
                                                 at com.integration.CreateBoardActivity.access$900(CreateBoardActivity.java:72)
                                                 at com.duodian.morespace.integration.CreateBoardActivity$10.run(CreateBoardActivity.java:371)
                                                 at java.lang.Thread.run(Thread.java:761)
                                              Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                 at android.os.Handler.<init>(Handler.java:200)
                                                 at android.os.Handler.<init>(Handler.java:114)
                                                 at android.widget.Toast$TN$2.<init>(Toast.java:336)
                                                 at android.widget.Toast$TN.<init>(Toast.java:336)
                                                 at android.widget.Toast.<init>(Toast.java:103)
                                                 at android.widget.Toast.makeText(Toast.java:256)
                                                 at com.utils.ToastUtil.<clinit>(ToastUtil.java:20)
                                                 at com.utils.ToastUtil.show(ToastUtil.java:24) 
                                                 at com.utils.ErrorInfo.showError(ErrorInfo.java:43) 
                                                 at com.integration.CreateBoardActivity.allotModerators(CreateBoardActivity.java:392) 
                                                 at com.integration.CreateBoardActivity.access$900(CreateBoardActivity.java:72) 
                                                 at com.integration.CreateBoardActivity$10.run(CreateBoardActivity.java:371) 
                                                 at java.lang.Thread.run(Thread.java:761) 

最佳答案

问题不在于Handler在你的里面 ToastUtil但是 Handler里面Toast

TN 的实例在 Toast 的构造函数中创建.

public Toast(Context context) {
    mContext = context;
    mTN = new TN();
    ......
}

TN包含一个成员字段,它是一个处理程序。

private static class TN extends ITransientNotification.Stub {
    ......
    final Handler mHandler = new Handler();  
    ......
}  

当你使用 ToastUtil第一次在普通线程中,那个 TN 的处理程序将在该线程中初始化,没有导致崩溃的循环程序。

您应该使用 ToastUtil在主线程或具有循环程序的线程中。

只需更改 ToastUtil 就有一个解决方案.

不要制作toastscrollToast static 而不是在方法 show 中实例化它们或 showScrollToast .例如

public static void show(final String src) {
    if (StringUtils.isEmpty(src)) {
        return;
    }
    r.post(new Runnable() {
        @Override
        public void run() {
            Toast toast = Toast.makeText(MainApplication.getApp(),"",Toast.LENGTH_SHORT);
            toast.setText(src);
            toast.show();
       }
    });
    Logger.d("Toast", src);
}

关于android - ExceptionInInitializerError & 无法在未调用 Looper.prepare() 的线程内创建处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44714992/

相关文章:

android - 在框架布局中将 imageView 置于顶部

javascript - Javascript 事件处理程序未按预期触发

r - R 中条件对象的处理

handler - 什么是处理程序?

python - 如何在python中单击toast通知时执行功能?

java - Toast Message 不消失

android - Firebase 将数据库从一个 Android 应用程序传输或复制到另一个

android - Kotlin协程:与工作计划有关。(invokeOnCompletion)

android - Android中如何查询彩信登录

android - Android : a simple example 上的自定义 toast