maoruibin / maoruibin.github.com

personal blog
http://gudong.site
MIT License
21 stars 5 forks source link

Hook Toast,更改内部 Handler 的实现 #80

Open maoruibin opened 5 years ago

maoruibin commented 5 years ago

核心代码

private void hookToast(Toast toast) {

    try {
        Field fieldTN = Toast.class.getDeclaredField("mTN");
        fieldTN.setAccessible(true);

        Field filedHandler = fieldTN.getType().getDeclaredField("mHandler");
        filedHandler.setAccessible(true);

        Object tn = fieldTN.get(toast);
        Handler preHandler = (Handler) filedHandler.get(tn);
        filedHandler.set(tn,new ToastHandlerWarp(preHandler));

    } catch (Exception e) {
        e.printStackTrace();
    }
}

ToastHandlerWarp.java


public class ToastHandlerWarp extends Handler{
    private static final String TAG = "ToastHandlerWarp";
    private Handler mOriginHandler;
    public ToastHandlerWarp(Handler preHandler) {
        this.mOriginHandler = preHandler;
    }

    @Override
    public void dispatchMessage(Message msg) {
        try {
            Log.d(TAG,"execute ToastHandlerWarp dispatchMessage");
            mOriginHandler.dispatchMessage(msg);
        }catch (Exception e){
            // ignore
        }
    }

    @Override
    public void handleMessage(Message msg) {
        Log.d(TAG,"execute ToastHandlerWarp handleMessage");
        mOriginHandler.handleMessage(msg);
    }
}

使用

Toast toast = Toast.makeText(v.getContext(), "测试Crash", Toast.LENGTH_SHORT);
hookToast(toast);
toast.show();

参考

逻辑分析见以下两篇不错的文章

简书一篇不错的讲解 Hook 的文章