2017-06-23 13 views
0

1.I iはLooper.getMainLooper()ExceptionInInitializerError&Looper.prepareを呼び出していないスレッド内のハンドラを作成できません()

設定している

2.andスレッドで乾杯したい。しかし、それはまだ をクラッシュ私は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

トーストを外部クラスに表示するには、アクティビティコンテキストを渡す必要があります。このようにして、アクティビティからスタイルを継承することができます。 – MatPag

答えて

2

問題はあなたのToastUtil内部Handlerではなく、Toast内部Handler

のコンストラクタにTNのインスタンスが作成されます。

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

そして、には、ハンドラであるメンバフィールドが含まれています。

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

初めて通常のスレッドでToastUtilを使用すると、そのTNのハンドラは、クラッシュの原因となるルーパーせずに、そのスレッドに初期化されます。

メインスレッドまたはルーパーを持つスレッドでToastUtilを使用する必要があります。

ToastUtilを変更するだけで解決策があります。

toastまたはscrollToast静的ではなく、法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で初期化することもできます)

関連する問題