version 7.x de Toast ajouté authentification par jeton, cela est correct, mais l'appel à show () est affiché Toast, s'il est coincé le thread principal opération de temps sur cinq secondes, il lancera une BadTokenException d'exception, et système 8.x départ, Google est menée dans le try-catch. Et le système 7.x est une douleur permanente, ne peut compter que sur notre propre pour réparer le.
Un programme de réhabilitation
Agent View, contexte de réflexion, réalisée dans le contexte try-catch, traitement de problème de BadTokenException de Toast
- BadTokenListener, Toast jeter auditeurs BadTokenException
public interface BadTokenListener {
/** * 当Toast抛出BadTokenException时回调 * * @param toast 发生异常的Toast实例 */ void onBadTokenCaught(@NonNull Toast toast); }
- SafeToastContext, enveloppé utilisation Toast du contexte
public class SafeToastContext extends ContextWrapper { private Toast mToast; private BadTokenListener mBadTokenListener; public SafeToastContext(Context base, Toast toast) { super(base); mToast = toast; } public void setBadTokenListener(@NonNull BadTokenListener badTokenListener) { mBadTokenListener = badTokenListener; } @Override public Context getApplicationContext() { //代理原本的Context return new ApplicationContextWrapper(super.getApplicationContext()); } private class ApplicationContextWrapper extends ContextWrapper { public ApplicationContextWrapper(Context base) { super(base); } @Override public Object getSystemService(String name) { if (Context.WINDOW_SERVICE.equals(name)) { //获取原来的WindowManager,交给WindowManagerWrapper代理,捕获BadTokenException异常 Context baseContext = getBaseContext(); return new WindowManagerWrapper((WindowManager) baseContext.getSystemService(name)); } return super.getSystemService(name); } } private class WindowManagerWrapper implements WindowManager { /** * 被包裹的WindowManager实例 */ private WindowManager mImpl; public WindowManagerWrapper(@NonNull WindowManager readImpl) { mImpl = readImpl; } @Override public Display getDefaultDisplay() { return mImpl.getDefaultDisplay(); } @Override public void removeViewImmediate(View view) { mImpl.removeViewImmediate(view); } @Override public void addView(View view, ViewGroup.LayoutParams params) { //在addView动刀,捕获BadTokenException异常 try { mImpl.addView(view, params); } catch (BadTokenException e) { e.printStackTrace(); if (mBadTokenListener != null) { mBadTokenListener.onBadTokenCaught(mToast); } } } @Override public void updateViewLayout(View view, ViewGroup.LayoutParams params) { mImpl.updateViewLayout(view, params); } @Override public void removeView(View view) { mImpl.removeView