diff --git a/README-en.md b/README-en.md index c128a7b..907e5b3 100644 --- a/README-en.md +++ b/README-en.md @@ -4,7 +4,7 @@ * Project address: [Github](https://github.com/getActivity/Toaster) -* [Click here to download demo apk directly](https://github.com/getActivity/Toaster/releases/download/12.5/Toaster.apk) +* [Click here to download demo apk directly](https://github.com/getActivity/Toaster/releases/download/12.6/Toaster.apk) ![](picture/en/demo_toast_activity.jpg) ![](picture/en/demo_toast_style_white.jpg) ![](picture/en/demo_toast_style_black.jpg) @@ -49,7 +49,7 @@ android { dependencies { // Toast framework:https://github.com/getActivity/Toaster - implementation 'com.github.getActivity:Toaster:12.5' + implementation 'com.github.getActivity:Toaster:12.6' } ``` @@ -142,7 +142,7 @@ Toaster.getInterceptor(); | Function or detail | [Toaster](https://github.com/getActivity/Toaster) |[ AndroidUtilCode-ToastUtils ](https://github.com/Blankj/AndroidUtilCode)| [Toasty](https://github.com/GrenderG/Toasty) | | :----: | :------: | :-----: | :-----: | -| Corresponding version | 12.5 | 1.30.6 | 1.5.0 | +| Corresponding version | 12.6 | 1.30.6 | 1.5.0 | | Number of issues | [![](https://img.shields.io/github/issues/getActivity/Toaster.svg)](https://github.com/getActivity/Toaster/issues) |[![](https://img.shields.io/github/issues/Blankj/AndroidUtilCode.svg)](https://github.com/Blankj/AndroidUtilCode/issues)| [![](https://img.shields.io/github/issues/GrenderG/Toasty.svg)](https://github.com/GrenderG/Toasty/issues) | | Framework pack size | 31 KB | 500 KB | 50 KB | | Framework maintenance status| 维护中 | 停止维护 | 停止维护 | diff --git a/README.md b/README.md index ca824b2..8062559 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ * 博客地址:[只需体验三分钟,你就会跟我一样,爱上这款 Toast](https://www.jianshu.com/p/9b174ee2c571) -* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/Toaster/releases/download/12.5/Toaster.apk) +* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/Toaster/releases/download/12.6/Toaster.apk) ![](picture/zh/download_demo_apk_qr_code.png) @@ -53,7 +53,7 @@ android { dependencies { // 吐司框架:https://github.com/getActivity/Toaster - implementation 'com.github.getActivity:Toaster:12.5' + implementation 'com.github.getActivity:Toaster:12.6' } ``` @@ -146,7 +146,7 @@ Toaster.getInterceptor(); | 功能或细节 | [Toaster](https://github.com/getActivity/Toaster) | [AndroidUtilCode-ToastUtils](https://github.com/Blankj/AndroidUtilCode) | [Toasty](https://github.com/GrenderG/Toasty) | | :----: | :------: | :-----: | :-----: | -| 对应版本 | 12.5 | 1.30.6 | 1.5.0 | +| 对应版本 | 12.6 | 1.30.6 | 1.5.0 | | issues 数 | [![](https://img.shields.io/github/issues/getActivity/Toaster.svg)](https://github.com/getActivity/Toaster/issues) | [![](https://img.shields.io/github/issues/Blankj/AndroidUtilCode.svg)](https://github.com/Blankj/AndroidUtilCode/issues) | [![](https://img.shields.io/github/issues/GrenderG/Toasty.svg)](https://github.com/GrenderG/Toasty/issues) | | 框架体积 | 32 KB | 500 KB | 50 KB | | 框架维护状态 | 维护中 | 停止维护 | 停止维护 | diff --git a/app/build.gradle b/app/build.gradle index 138a8ec..ee54396 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.hjq.toast.demo" minSdkVersion 16 targetSdkVersion 33 - versionCode 1205 - versionName "12.5" + versionCode 1206 + versionName "12.6" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/build.gradle b/build.gradle index 574c1b4..7d9f8a8 100644 --- a/build.gradle +++ b/build.gradle @@ -31,8 +31,23 @@ allprojects { jcenter() } - // 将构建文件统一输出到项目根目录下的 build 文件夹 - setBuildDir(new File(rootDir, "build/${path.replaceAll(':', '/')}")) + // 读取 local.properties 文件配置 + def properties = new Properties() + def localPropertiesFile = rootProject.file("local.properties") + if (localPropertiesFile.exists()) { + localPropertiesFile.withInputStream { inputStream -> + properties.load(inputStream) + } + } + + String buildDirPath = properties.getProperty("build.dir") + if (buildDirPath != null && buildDirPath != "") { + // 将构建文件统一输出到指定的目录下 + setBuildDir(new File(buildDirPath, rootProject.name + "/build/${path.replaceAll(':', '/')}")) + } else { + // 将构建文件统一输出到项目根目录下的 build 文件夹 + setBuildDir(new File(rootDir, "build/${path.replaceAll(':', '/')}")) + } } tasks.register('clean', Delete) { diff --git a/library/build.gradle b/library/build.gradle index 17d715a..ff23cca 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,8 +5,8 @@ android { defaultConfig { minSdkVersion 14 - versionCode 1205 - versionName "12.5" + versionCode 1206 + versionName "12.6" } // 使用 JDK 1.8 diff --git a/library/src/main/java/com/hjq/toast/ActivityStack.java b/library/src/main/java/com/hjq/toast/ActivityStack.java index d3ddcd7..c8928ee 100644 --- a/library/src/main/java/com/hjq/toast/ActivityStack.java +++ b/library/src/main/java/com/hjq/toast/ActivityStack.java @@ -19,7 +19,7 @@ final class ActivityStack implements Application.ActivityLifecycleCallbacks { public static ActivityStack getInstance() { if(sInstance == null) { synchronized (ActivityStack.class) { - if(sInstance == null) { + if (sInstance == null) { sInstance = new ActivityStack(); } } diff --git a/library/src/main/java/com/hjq/toast/NotificationServiceProxy.java b/library/src/main/java/com/hjq/toast/NotificationServiceProxy.java index 224629d..7957321 100644 --- a/library/src/main/java/com/hjq/toast/NotificationServiceProxy.java +++ b/library/src/main/java/com/hjq/toast/NotificationServiceProxy.java @@ -7,15 +7,15 @@ * author : Android 轮子哥 * github : https://github.com/getActivity/Toaster * time : 2021/11/13 - * desc : 通知服务代理代理对象 + * desc : 通知服务代理对象 */ final class NotificationServiceProxy implements InvocationHandler { /** 被代理的对象 */ - private final Object mSource; + private final Object mRealObject; - public NotificationServiceProxy(Object source) { - mSource = source; + public NotificationServiceProxy(Object realObject) { + mRealObject = realObject; } @Override @@ -25,13 +25,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl case "enqueueToastEx": case "cancelToast": // 将包名修改成系统包名,这样就可以绕过系统的拦截 - // 部分华为机将 enqueueToast 修改成了 enqueueToastEx + // 部分华为机将 enqueueToast 方法名修改成了 enqueueToastEx args[0] = "android"; break; default: break; } // 使用动态代理 - return method.invoke(mSource, args); + return method.invoke(mRealObject, args); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/toast/ToastImpl.java b/library/src/main/java/com/hjq/toast/ToastImpl.java index 7ec2ce3..bf80329 100644 --- a/library/src/main/java/com/hjq/toast/ToastImpl.java +++ b/library/src/main/java/com/hjq/toast/ToastImpl.java @@ -112,12 +112,18 @@ private void trySendAccessibilityEvent(View view) { if (!accessibilityManager.isEnabled()) { return; } - // 将 Toast 视为通知,因为它们用于向用户宣布短暂的信息 - AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); + int eventType = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED; + AccessibilityEvent event; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + event = new AccessibilityEvent(); + event.setEventType(eventType); + } else { + event = AccessibilityEvent.obtain(eventType); + } event.setClassName(Toast.class.getName()); event.setPackageName(context.getPackageName()); view.dispatchPopulateAccessibilityEvent(event); + // 将 Toast 视为通知,因为它们用于向用户宣布短暂的信息 accessibilityManager.sendAccessibilityEvent(event); } @@ -162,7 +168,6 @@ public void run() { } try { - windowManager.addView(mToast.getView(), params); // 添加一个移除吐司的任务 HANDLER.postDelayed(() -> cancel(), mToast.getDuration() == Toast.LENGTH_LONG ? diff --git a/library/src/main/java/com/hjq/toast/ToastStrategy.java b/library/src/main/java/com/hjq/toast/ToastStrategy.java index c598321..3e3a57f 100644 --- a/library/src/main/java/com/hjq/toast/ToastStrategy.java +++ b/library/src/main/java/com/hjq/toast/ToastStrategy.java @@ -7,6 +7,8 @@ import android.app.NotificationManager; import android.content.Context; import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; @@ -47,7 +49,7 @@ public class ToastStrategy implements IToastStrategy { public static final int SHOW_STRATEGY_TYPE_QUEUE = 1; /** Handler 对象 */ - private final static Handler HANDLER = new Handler(Looper.getMainLooper()); + private static final Handler HANDLER = new Handler(Looper.getMainLooper()); /** * 默认延迟时间 @@ -79,6 +81,11 @@ public ToastStrategy() { this(ToastStrategy.SHOW_STRATEGY_TYPE_IMMEDIATELY); } + @Override + public void registerStrategy(Application application) { + mApplication = application; + } + public ToastStrategy(int type) { mShowStrategyType = type; switch (mShowStrategyType) { @@ -90,21 +97,16 @@ public ToastStrategy(int type) { } } - @Override - public void registerStrategy(Application application) { - mApplication = application; - ActivityStack.getInstance().register(application); - } - @Override public IToast createToast(ToastParams params) { - Activity foregroundActivity = ActivityStack.getInstance().getForegroundActivity(); + Activity foregroundActivity = getForegroundActivity(); IToast toast; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Settings.canDrawOverlays(mApplication)) { // 如果有悬浮窗权限,就开启全局的 Toast toast = new GlobalToast(mApplication); - } else if (foregroundActivity != null && !params.crossPageShow) { + } else if (!params.crossPageShow && foregroundActivity != null && !foregroundActivity.isFinishing() && + (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1 && !foregroundActivity.isDestroyed())) { // 如果没有悬浮窗权限,就开启一个依附于 Activity 的 Toast toast = new ActivityToast(foregroundActivity); } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) { @@ -267,17 +269,11 @@ protected boolean isChangeEnabledCompat(long changeId) { // 因为 Compatibility.isChangeEnabled() 普通应用根本调用不到,反射也不行 // 通过 Toast.isSystemRenderedTextToast 也没有办法反射到 // 最后发现反射 CompatChanges.isChangeEnabled 是可以的 - Class aClass = Class.forName("android.app.compat.CompatChanges"); - Method method = aClass.getMethod("isChangeEnabled", long.class); + Class clazz = Class.forName("android.app.compat.CompatChanges"); + Method method = clazz.getMethod("isChangeEnabled", long.class); method.setAccessible(true); return Boolean.parseBoolean(String.valueOf(method.invoke(null, changeId))); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { e.printStackTrace(); } return false; @@ -311,4 +307,11 @@ protected boolean areNotificationsEnabled(Context context) { } return true; } + + /** + * 获取前台的 Activity + */ + protected Activity getForegroundActivity() { + return ActivityStack.getInstance().getForegroundActivity(); + } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/toast/Toaster.java b/library/src/main/java/com/hjq/toast/Toaster.java index 0a4f4fb..2ce728c 100644 --- a/library/src/main/java/com/hjq/toast/Toaster.java +++ b/library/src/main/java/com/hjq/toast/Toaster.java @@ -66,7 +66,13 @@ public static void init(Application application, IToastStyle style) { * @param style Toast 样式 */ public static void init(Application application, IToastStrategy strategy, IToastStyle style) { + // 如果当前已经初始化过了,就不要再重复初始化了 + if (isInit()) { + return; + } + sApplication = application; + ActivityStack.getInstance().register(application); // 初始化 Toast 策略 if (strategy == null) {