diff --git a/README.md b/README.md index 2733a36..32b0111 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # 吐司工具类 +> 码云地址:[Gitee](https://gitee.com/getActivity/ToastUtils) + > 博客地址:[只需体验三分钟,你就会跟我一样,爱上这款Toast](https://www.jianshu.com/p/9b174ee2c571) -> 已投入公司项目多时,没有任何毛病,可胜任任何需求,[点击此处下载Demo](https://raw.githubusercontent.com/getActivity/ToastUtils/master/ToastUtils.apk) +> 已投入公司项目多时,没有任何毛病,可胜任任何需求,[点击此处下载Demo](ToastUtils.apk) > 想了解实现原理的可以点击此链接查看:[ToastUtils](https://github.com/getActivity/ToastUtils/blob/master/library/src/main/java/com/hjq/toast/ToastUtils.java) 源码 @@ -13,7 +15,7 @@ #### 集成步骤 dependencies { - implementation 'com.hjq:toast:8.2' + implementation 'com.hjq:toast:8.3' } #### 初始化 Toast diff --git a/ToastUtils.apk b/ToastUtils.apk index 083525c..59480ac 100644 Binary files a/ToastUtils.apk and b/ToastUtils.apk differ diff --git a/app/build.gradle b/app/build.gradle index c517482..3f80fd5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.hjq.toast.demo" minSdkVersion 14 targetSdkVersion 28 - versionCode 82 - versionName "8.2" + versionCode 83 + versionName "8.3" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -26,7 +26,7 @@ dependencies { // 标题栏:https://github.com/getActivity/TitleBar implementation 'com.hjq:titlebar:6.0' // 悬浮窗:https://github.com/getActivity/XToast - implementation 'com.hjq:xtoast:5.0' + implementation 'com.hjq:xtoast:5.5' // 内存泄漏捕捉:https://github.com/square/leakcanary - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4' } \ No newline at end of file diff --git a/app/src/main/java/com/hjq/toast/demo/ToastApplication.java b/app/src/main/java/com/hjq/toast/demo/ToastApplication.java index f514765..c285ec1 100644 --- a/app/src/main/java/com/hjq/toast/demo/ToastApplication.java +++ b/app/src/main/java/com/hjq/toast/demo/ToastApplication.java @@ -27,7 +27,7 @@ public boolean intercept(Toast toast, CharSequence text) { if (intercept) { Log.e("Toast", "空 Toast"); } else { - Log.i("Toast", text.toString()); + Log.d("Toast", text.toString()); } return intercept; } diff --git a/library/build.gradle b/library/build.gradle index ebb3c0c..4dbc59a 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -7,8 +7,8 @@ android { defaultConfig { minSdkVersion 3 targetSdkVersion 26 - versionCode 82 - versionName "8.2" + versionCode 83 + versionName "8.3" } } @@ -16,7 +16,7 @@ publish { userOrg = 'getactivity' groupId = 'com.hjq' artifactId = 'toast' - version = '8.2' + version = '8.3' description = 'This is a very functional Toast' website = "https://github.com/getActivity/ToastUtils" } diff --git a/library/src/main/java/com/hjq/toast/ToastHelper.java b/library/src/main/java/com/hjq/toast/ToastHelper.java index a7621f8..54b26d5 100644 --- a/library/src/main/java/com/hjq/toast/ToastHelper.java +++ b/library/src/main/java/com/hjq/toast/ToastHelper.java @@ -1,6 +1,8 @@ package com.hjq.toast; +import android.app.Activity; import android.app.Application; +import android.content.Context; import android.graphics.PixelFormat; import android.os.Handler; import android.os.Looper; @@ -95,16 +97,24 @@ void show() { params.y = mToast.getYOffset(); try { - // 如果这个 View 对象被重复添加到 WindowManager 则会抛出异常 - // java.lang.IllegalStateException: - // View android.widget.TextView has already been added to the window manager. - mWindowHelper.getWindowManager().addView(mToast.getView(), params); + Activity topActivity = mWindowHelper.getTopActivity(); + if (topActivity != null && !topActivity.isFinishing()) { + WindowManager windowManager = (WindowManager) topActivity.getSystemService(Context.WINDOW_SERVICE); + if (windowManager != null) { + windowManager.addView(mToast.getView(), params); + } + } // 添加一个移除吐司的任务 sendEmptyMessageDelayed(hashCode(), mToast.getDuration() == Toast.LENGTH_LONG ? IToastStrategy.LONG_DURATION_TIMEOUT : IToastStrategy.SHORT_DURATION_TIMEOUT); // 当前已经显示 setShow(true); - } catch (NullPointerException | IllegalStateException | WindowManager.BadTokenException ignored) {} + } catch (IllegalStateException | WindowManager.BadTokenException ignored) { + // 如果这个 View 对象被重复添加到 WindowManager 则会抛出异常 + // java.lang.IllegalStateException: View android.widget.TextView has already been added to the window manager. + // 如果 WindowManager 绑定的 Activity 已经销毁,则会抛出异常 + // android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@ef1ccb6 is not valid; is your activity running? + } } } @@ -116,11 +126,17 @@ void cancel() { removeMessages(hashCode()); if (isShow()) { try { + Activity topActivity = mWindowHelper.getTopActivity(); + if (topActivity != null) { + WindowManager windowManager = (WindowManager) topActivity.getSystemService(Context.WINDOW_SERVICE); + if (windowManager != null) { + windowManager.removeViewImmediate(mToast.getView()); + } + } + } catch (IllegalArgumentException ignored) { // 如果当前 WindowManager 没有附加这个 View 则会抛出异常 - // java.lang.IllegalArgumentException: - // View=android.widget.TextView not attached to window manager - mWindowHelper.getWindowManager().removeViewImmediate(mToast.getView()); - } catch (NullPointerException | IllegalArgumentException ignored) {} + // java.lang.IllegalArgumentException: View=android.widget.TextView not attached to window manager + } // 当前没有显示 setShow(false); } diff --git a/library/src/main/java/com/hjq/toast/WindowHelper.java b/library/src/main/java/com/hjq/toast/WindowHelper.java index d8415df..5ab23b9 100644 --- a/library/src/main/java/com/hjq/toast/WindowHelper.java +++ b/library/src/main/java/com/hjq/toast/WindowHelper.java @@ -3,10 +3,8 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.Application; -import android.content.Context; import android.os.Build; import android.os.Bundle; -import android.view.WindowManager; /** * author : Android 轮子哥 @@ -34,19 +32,10 @@ static WindowHelper register(ToastHelper toast, Application application) { } /** - * 获取一个WindowManager对象 - * - * @return 如果获取不到则抛出空指针异常 + * 获取栈顶的 Activity */ - WindowManager getWindowManager() throws NullPointerException { - // 如果使用的 WindowManager 对象不是当前 Activity 创建的,则会抛出异常 - // android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application - // 如果使用的 WindowManager 对象的 Activity 已经销毁,则会抛出异常 - // WindowManager: android.view.WindowLeaked: Activity has leaked window TextView that was originally added here - if (mTopActivity != null && !mTopActivity.isFinishing()) { - return ((WindowManager) mTopActivity.getSystemService(Context.WINDOW_SERVICE)); - } - throw new NullPointerException(); + Activity getTopActivity() { + return mTopActivity; } /**