Skip to content

Instantly share code, notes, and snippets.

@shaobin0604
Created June 10, 2019 03:09
Show Gist options
  • Save shaobin0604/185b40fc20a6b0717aeb8cd6361b78b3 to your computer and use it in GitHub Desktop.
Save shaobin0604/185b40fc20a6b0717aeb8cd6361b78b3 to your computer and use it in GitHub Desktop.
Safe Toast to resolve BadTokenException on Android 7.x
package com.tmall.android.toast;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.StringRes;
import android.widget.Toast;
import java.lang.reflect.Field;
public class SafeToast {
private static Field sField_TN;
private static Field sField_TN_Handler;
private static Toast mToast;
static {
try {
sField_TN = Toast.class.getDeclaredField("mTN");
sField_TN.setAccessible(true);
sField_TN_Handler = sField_TN.getType().getDeclaredField("mHandler");
sField_TN_Handler.setAccessible(true);
} catch (Exception e) {
}
}
private SafeToast() {
}
public static void show(Context context, CharSequence message, int duration) {
if (mToast == null) {
mToast = Toast.makeText(context.getApplicationContext(), message, duration);
hook(mToast);
} else {
mToast.setDuration(duration);
mToast.setText(message);
}
mToast.show();
}
public static void show(Context context, @StringRes int resId, int duration) {
if (mToast == null) {
mToast = Toast.makeText(context.getApplicationContext(), resId, duration);
hook(mToast);
} else {
mToast.setDuration(duration);
mToast.setText(context.getString(resId));
}
mToast.show();
}
private static void hook(Toast toast) {
try {
Object tn = sField_TN.get(toast);
Handler preHandler = (Handler) sField_TN_Handler.get(tn);
sField_TN_Handler.set(tn, new SafeHandler(preHandler));
} catch (Exception e) {
}
}
private static class SafeHandler extends Handler {
private Handler impl;
public SafeHandler(Handler impl) {
this.impl = impl;
}
@Override
public void dispatchMessage(Message msg) {
try {
super.dispatchMessage(msg);
} catch (Exception e) {
}
}
@Override
public void handleMessage(Message msg) {
impl.handleMessage(msg);//需要委托给原Handler执行
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment