Skip to content

Commit

Permalink
修复 Toast 没有跟随 Activity 生命周期的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
getActivity committed Jun 28, 2020
1 parent 0786946 commit 39fdd7d
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 33 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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) 源码
Expand All @@ -13,7 +15,7 @@
#### 集成步骤

dependencies {
implementation 'com.hjq:toast:8.2'
implementation 'com.hjq:toast:8.3'
}

#### 初始化 Toast
Expand Down
Binary file modified ToastUtils.apk
Binary file not shown.
8 changes: 4 additions & 4 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 14
targetSdkVersion 28
versionCode 82
versionName "8.2"
versionCode 83
versionName "8.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand All @@ -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'
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/hjq/toast/demo/ToastApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ android {
defaultConfig {
minSdkVersion 3
targetSdkVersion 26
versionCode 82
versionName "8.2"
versionCode 83
versionName "8.3"
}
}

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"
}
Expand Down
34 changes: 25 additions & 9 deletions library/src/main/java/com/hjq/toast/ToastHelper.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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?
}
}
}

Expand All @@ -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);
}
Expand Down
17 changes: 3 additions & 14 deletions library/src/main/java/com/hjq/toast/WindowHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 轮子哥
Expand Down Expand Up @@ -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;
}

/**
Expand Down

0 comments on commit 39fdd7d

Please sign in to comment.