Skip to content

Commit

Permalink
修复多次设置 Toast 策略会导致多次注册 Activity 生命周期监听的问题
Browse files Browse the repository at this point in the history
优化框架中部分字段命名、参数命名、代码写法、代码注释
  • Loading branch information
getActivity committed Nov 12, 2023
1 parent 5804d7c commit 6590f50
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 41 deletions.
6 changes: 3 additions & 3 deletions README-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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'
}
```

Expand Down Expand Up @@ -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| 维护中 | 停止维护 | 停止维护 |
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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'
}
```

Expand Down Expand Up @@ -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 |
| 框架维护状态 | 维护中 | 停止维护 | 停止维护 |
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

Expand Down
19 changes: 17 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ android {

defaultConfig {
minSdkVersion 14
versionCode 1205
versionName "12.5"
versionCode 1206
versionName "12.6"
}

// 使用 JDK 1.8
Expand Down
2 changes: 1 addition & 1 deletion library/src/main/java/com/hjq/toast/ActivityStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
13 changes: 9 additions & 4 deletions library/src/main/java/com/hjq/toast/ToastImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -162,7 +168,6 @@ public void run() {
}

try {

windowManager.addView(mToast.getView(), params);
// 添加一个移除吐司的任务
HANDLER.postDelayed(() -> cancel(), mToast.getDuration() == Toast.LENGTH_LONG ?
Expand Down
39 changes: 21 additions & 18 deletions library/src/main/java/com/hjq/toast/ToastStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());

/**
* 默认延迟时间
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -311,4 +307,11 @@ protected boolean areNotificationsEnabled(Context context) {
}
return true;
}

/**
* 获取前台的 Activity
*/
protected Activity getForegroundActivity() {
return ActivityStack.getInstance().getForegroundActivity();
}
}
6 changes: 6 additions & 0 deletions library/src/main/java/com/hjq/toast/Toaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 6590f50

Please sign in to comment.