2017-06-23 85 views
0

1.I想在一个线程的ExceptionInInitializerError&不能内螺纹已不叫Looper.prepare创建处理程序()

2.and我已经设置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)  
+0

您应该传递Activity上下文以在外部类中显示Toast。通过这种方式,您可以继承Activity中的样式。 – MatPag

回答

2

的问题是不是你的ToastUtilHandlerHandlerToast

Toast的构造函数中创建了一个TN的实例。

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静态实例,而不是他们的方法showshowScrollToast。例如

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

Thx!这是问题的关键! – Werb

0

我认为,以这种方式使用的工具会更好:

public class ToastUtil { 
    //if you don't care about the toast style you can pass the Application 
    //context instead of the Activity one 
    public static void show(Context context, @StringRes int stringRes) { 
     String message = context.getResources().getString(stringRes); 
     Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 
     Logger.d("Toast", message); 
    } 
} 

,然后使用本这样的:

ToastUtil.show(context, R.string.my_message); 

如果你想完全忽略活动风格,您应该为传递该应用程序的类添加一个构造函数,然后您可以调用每个静态方法而不必一遍又一遍地传递上下文。 (或者您也可以在每个活动扩展的BaseActivity中初始化此实用程序)

相关问题