2017-06-23 3 views
0

1.I veulent griller dans un filExceptionInInitializerError et ne peut pas créer gestionnaire intérieur thread qui n'a pas appelé Looper.prepare()

j'ai mis 2. Et Looper.getMainLooper()

Mais planter encore Je sais peut utiliser activity.runOnUiThread résoudre ce problème mais je veux trouver une autre méthode à résoudre, il suffit de changer ToastUtil.

S'il vous plaît, Merci d'avance

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

Crashlog:

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

Vous devez passer le contexte d'activité pour afficher un Toast dans une classe externe. De cette façon, vous pouvez hériter du style de l'activité. – MatPag

Répondre

2

Le problème n'est pas le Handler dans votre ToastUtil mais l'intérieur HandlerToast.

Une instance de TN est créée dans le constructeur de Toast.

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

Et TN contient un champ de membre qui est un gestionnaire.

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

Lorsque vous utilisez ToastUtil dans un fil normal pour la première fois, le gestionnaire de ce TN sera initialisé dans ce thread sans looper qui provoque l'accident.

Vous devez utiliser ToastUtil dans le thread principal ou dans un thread doté d'un boucleur.

Il existe une solution en changeant simplement ToastUtil.

Ne commettez pas l'toast ou scrollToaststatique au lieu de les instancier dans la méthode show ou showScrollToast. par exemple.

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! C'est le noeud du problème! – Werb

0

Je pense que l'utilisation de l'utilitaire de cette façon serait mieux:

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

Et puis utilisez cela comme ceci:

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

Si vous voulez ignorer complètement le style d'activité , vous devez ajouter un constructeur à la classe qui transmet l'application, puis vous pouvez appeler chaque méthode statique sans passer le contexte encore et encore. (ou en alternative, vous pouvez initialiser cet utilitaire dans une BaseActivity que chaque activité étend)