/ToastCompat

ToastCompat for Android 7.1.1, Avoiding Toast BadTokenException

Primary LanguageJava

ToastCompat

ToastCompat for Android 7.1.1, Avoiding Toast BadTokenException , Just what exactly the repo ToastCompat do. I name this repo "ToastCompat" just want somebody could be help.

已知问题:对部分OPPO的机型JAVA反射无效,我手上没有OPPO的手机,无法尝试~希望有人能帮助一下。

Why

for more details about BadTokenException on Toast

There is ToastCompat do the same thing , why i create this?

ToastCompat use a windowmanager wrapper to hook the system windowmanager. It is a great solution to fix the bug. But when i test in the phone( Nubia Z17S),the Toast can't be show. I can't find the reason for it, It is weird,but it do happen. I had reported a bug to the author.

So i have to find another solution to fix the bug BadTokenException

Solution

Just copy ToastCompat.java to your project,and use it like Toast.

these is the main code to solve the issue:

    @Override
    public void show() {
        if(checkIfNeedToHack()){
            tryToHack();
        }
        super.show();
    }

    protected boolean checkIfNeedToHack(){
        return Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1;
    }

    private void tryToHack(){
        try {
            Object mTN=getFieldValue(this,"mTN");
            if(mTN!=null){
                Object rawHandler=getFieldValue(mTN,"mHandler");
                if(rawHandler!=null){
                    setFieldValue(rawHandler,"mCallback",new InternalHandlerCallback((Handler)rawHandler));
                }
            }
        }catch (Throwable e){
            e.printStackTrace();
        }
    }

    private class InternalHandlerCallback implements Handler.Callback{
        private final Handler mHandler;

        public InternalHandlerCallback(Handler mHandler) {
            this.mHandler = mHandler;
        }

        @Override
        public boolean handleMessage(Message msg) {
            try {
                mHandler.handleMessage(msg);
            }catch (Throwable e) {
               e.printStackTrace();
            }
            return true;
        }
    }