SingleToastUtil改为使用Toast框架

This commit is contained in:
huangjian
2021-11-16 15:00:41 +08:00
parent bdd59a1e2d
commit 58066c0f8f
9 changed files with 33 additions and 335 deletions

View File

@@ -26,6 +26,7 @@ import com.alibaba.security.rp.RPSDK;
import com.bumptech.glide.request.target.ViewTarget;
import com.bytedance.hume.readapk.HumeSDK;
import com.coorchice.library.utils.LogUtils;
import com.hjq.toast.ToastUtils;
import com.huawei.hms.support.common.ActivityMgr;
import com.idlefish.flutterboost.FlutterBoost;
import com.llew.huawei.verifier.LoadedApkHuaWei;
@@ -207,6 +208,8 @@ public class XChatApplication extends Application {
}
});
ToastUtils.init(this);
if (inMainProcess(this)) {
// 注册自定义推送消息处理,这个是可选项
NIMPushClient.registerMixPushMessageHandler(new PushMessageHandler());

View File

@@ -856,11 +856,11 @@ public abstract class BaseActivity extends RxAppCompatActivity
* @param length
*/
public void toast(int resId, int length) {
SingleToastUtil.showToast(BasicConfig.INSTANCE.getAppContext(), resId, length);
SingleToastUtil.showToast(resId);
}
public void toast(String toast, int length) {
SingleToastUtil.showToast(BasicConfig.INSTANCE.getAppContext(), toast, length);
SingleToastUtil.showToast(toast);
}

View File

@@ -6,6 +6,7 @@ import androidx.fragment.app.Fragment;
import android.view.View;
import android.widget.Toast;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
import com.yizhuan.erban.R;
@@ -21,7 +22,7 @@ public abstract class AbsStatusFragment extends Fragment implements IStatusFragm
}
public void checkNetToast(){
Toast.makeText(BasicConfig.INSTANCE.getAppContext(), R.string.str_network_not_capable, Toast.LENGTH_SHORT).show();
SingleToastUtil.showToast(R.string.str_network_not_capable);
}
@Override

View File

@@ -6,6 +6,7 @@ import android.os.Looper;
import android.widget.Toast;
import com.yizhuan.erban.R;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
/**
* Created by qinbo on 2014/7/2.
@@ -81,7 +82,7 @@ public class TimeOutProgressDialog {
// if (!NetworkUtils.isNetworkAvailable(mContext)) {
// Toast.makeText(mContext,R.string.str_network_not_capable, Toast.LENGTH_LONG).show();
// } else {
Toast.makeText(mContext, R.string.str_network_not_capable, Toast.LENGTH_LONG).show();
SingleToastUtil.showToast(R.string.str_network_not_capable);
//}
//}
}

View File

@@ -1,212 +0,0 @@
package com.yizhuan.erban.ui.widget.marqueeview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExToast {
private static final String TAG = "ExToast";
public static final int LENGTH_ALWAYS = 0;
public static final int LENGTH_SHORT = 2;
public static final int LENGTH_LONG = 4;
private Toast toast;
private Context mContext;
private int mDuration = LENGTH_SHORT;
private int animations = -1;
private boolean isShow = false;
private Object mTN;
private Object mGetService;
private Method mAsBinder;
private Method show;
private Method hide;
private Handler handler = new Handler();
public ExToast(Context context) {
this.mContext = context;
if (toast == null) {
toast = new Toast(mContext);
}
}
private Runnable hideRunnable = this::hide;
/**
* Show the view for the specified duration.
*/
public void show() {
if (isShow) return;
initTN();
try {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
show.invoke(mTN);
} else {
show.invoke(mTN, toast.getView().getWindowToken()/*mAsBinder.invoke(mGetService)*/);
}
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
isShow = true;
//判断duration如果大于#LENGTH_ALWAYS 则设置消失时间
if (mDuration > LENGTH_ALWAYS) {
handler.postDelayed(hideRunnable, mDuration * 1000);
}
}
/**
* Close the view if it's showing, or don't show it if it isn't showing yet.
* You do not normally have to call this. Normally view will disappear on its own
* after the appropriate duration.
*/
public void hide() {
if (!isShow) return;
try {
hide.invoke(mTN);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
isShow = false;
}
public void setView(View view) {
toast.setView(view);
}
public View getView() {
return toast.getView();
}
/**
* Set how long to show the view for.
*
* @see #LENGTH_SHORT
* @see #LENGTH_LONG
* @see #LENGTH_ALWAYS
*/
public void setDuration(int duration) {
mDuration = duration;
}
public int getDuration() {
return mDuration;
}
public void setMargin(float horizontalMargin, float verticalMargin) {
toast.setMargin(horizontalMargin, verticalMargin);
}
public float getHorizontalMargin() {
return toast.getHorizontalMargin();
}
public float getVerticalMargin() {
return toast.getVerticalMargin();
}
public void setGravity(int gravity, int xOffset, int yOffset) {
toast.setGravity(gravity, xOffset, yOffset);
}
public int getGravity() {
return toast.getGravity();
}
public int getXOffset() {
return toast.getXOffset();
}
public int getYOffset() {
return toast.getYOffset();
}
public static ExToast makeText(Context context, CharSequence text, int duration) {
Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
ExToast exToast = new ExToast(context);
exToast.toast = toast;
exToast.mDuration = duration;
return exToast;
}
public static ExToast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return makeText(context, context.getResources().getText(resId), duration);
}
public void setText(int resId) {
setText(mContext.getText(resId));
}
public void setText(CharSequence s) {
toast.setText(s);
}
public int getAnimations() {
return animations;
}
public void setAnimations(int animations) {
this.animations = animations;
}
@SuppressLint("PrivateApi")
private void initTN() {
try {
Field tnField = toast.getClass().getDeclaredField("mTN");
tnField.setAccessible(true);
mTN = tnField.get(toast);
Method getService = toast.getClass().getDeclaredMethod("getService");
getService.setAccessible(true);
mGetService = getService.invoke(toast);
Method[] methods = mGetService.getClass().getMethods();
for (Method method : methods) {
if ("asBinder".equals(method.getName())) {
//public android.os.IBinder android.app.INotificationManager$Stub$Proxy.asBinder()
mAsBinder = method;
}
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
show = mTN.getClass().getMethod("show");
} else {
show = mTN.getClass().getMethod("show", IBinder.class);
}
hide = mTN.getClass().getMethod("hide");
/*设置动画*/
if (animations != -1) {
Field tnParamsField = mTN.getClass().getDeclaredField("mParams");
tnParamsField.setAccessible(true);
WindowManager.LayoutParams params = (WindowManager.LayoutParams) tnParamsField.get(mTN);
params.windowAnimations = animations;
}
/*调用tn.show()之前一定要先设置mNextView*/
Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView");
tnNextViewField.setAccessible(true);
tnNextViewField.set(mTN, toast.getView());
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -20,6 +20,7 @@ import androidx.annotation.IntDef;
import androidx.fragment.app.FragmentActivity;
import android.widget.Toast;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import com.zhihu.matisse.internal.ui.widget.IncapableDialog;
import java.lang.annotation.Retention;
@@ -76,7 +77,7 @@ public class IncapableCause {
break;
case TOAST:
default:
Toast.makeText(context, cause.mMessage, Toast.LENGTH_SHORT).show();
SingleToastUtil.showToast(cause.mMessage);
break;
}
}

View File

@@ -28,6 +28,7 @@ import android.view.ViewGroup;
import android.widget.Toast;
import com.yizhuan.erban.R;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import com.zhihu.matisse.internal.entity.Item;
import com.zhihu.matisse.internal.entity.SelectionSpec;
import com.zhihu.matisse.internal.utils.PhotoMetadataUtils;
@@ -73,7 +74,7 @@ public class PreviewItemFragment extends Fragment {
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(), R.string.error_no_video_activity, Toast.LENGTH_SHORT).show();
SingleToastUtil.showToast(R.string.error_no_video_activity);
}
}
});

View File

@@ -93,6 +93,8 @@ dependencies {
api "org.greenrobot:eventbus:${eventbusVersion}"
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'com.github.getActivity:ToastUtils:9.6'
}
repositories {
mavenCentral()

View File

@@ -2,149 +2,50 @@ package com.yizhuan.xchat_android_library.utils;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.widget.Toast;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
import java.lang.reflect.Field;
import com.hjq.toast.ToastUtils;
/**
* Created by qinbo on 2014/8/12.
*/
public class SingleToastUtil {
private static String oldMsg;
protected static Toast toast = null;
private static long oneTime = 0;
private static long twoTime = 0;
private static Handler handler;
public static void showToast(String s) {
showToast(BasicConfig.INSTANCE.getAppContext(), s, Toast.LENGTH_LONG);
ToastUtils.show(s);
}
public static void showToast(int resId) {
ToastUtils.show(resId);
}
@Deprecated
public static void showToastShort(String s) {
showToast(BasicConfig.INSTANCE.getAppContext(), s, Toast.LENGTH_SHORT);
ToastUtils.show(s);
}
@Deprecated
public static void showToastShort(int resId) {
showToast(BasicConfig.INSTANCE.getAppContext(), BasicConfig.INSTANCE.getAppContext().getString(resId), Toast.LENGTH_SHORT);
ToastUtils.show(resId);
}
@Deprecated
public static void showToast(Context context, String s) {
showToast(context, s, Toast.LENGTH_LONG);
}
private static void doShowToast(Context context, String s, int length) {
try {
if (toast == null) {
toast = Toast.makeText(context, s, length);
//尝试修复bugly上的一个大量崩溃
//bugly地址:https://bugly.qq.com/v2/crash-reporting/crashes/52320483a6/910?pid=1
//解决办法:https://blog.csdn.net/joye123/article/details/80738113
hook(toast);
toast.show();
oneTime = SystemClock.uptimeMillis();
} else {
twoTime = SystemClock.uptimeMillis();
if (s.equals(oldMsg)) {
if (twoTime - oneTime > (length == 0 ? 2000 : 3500)) {
toast.show(); // 频繁调用会出现无法展示的情况
oneTime = twoTime;
}
} else {
oldMsg = s;
toast.setText(s);
toast.show();
oneTime = twoTime;
}
}
}catch (Exception e){
}
ToastUtils.show(s);
}
@Deprecated
public static void showToast(Context mContext, final String s, final int length) {
if (TextUtils.isEmpty(s)) return;
// 内存泄露的解决
final Context context = BasicConfig.INSTANCE.getAppContext();
if (Looper.myLooper() != Looper.getMainLooper()) {
synchronized (SingleToastUtil.class) {
if (null == handler) {
handler = new Handler(Looper.getMainLooper());
}
}
handler.post(new Runnable() {
@Override
public void run() {
doShowToast(context, s, length);
}
});
} else {
doShowToast(context, s, length);
}
ToastUtils.show(s);
}
@Deprecated
public static void showToast(Context context, int resId, int length) {
showToast(context, context.getString(resId), length);
ToastUtils.show(resId);
}
@Deprecated
public static void showToast(Context context, int resId) {
showToast(context, resId, Toast.LENGTH_LONG);
ToastUtils.show(resId);
}
public static void replaceToast(Context context, String str) {
if (toast == null) {
showToast(context, str, Toast.LENGTH_LONG);
} else {
oldMsg = str;
toast.setText(str);
}
}
public static class SafelyHandlerWarpper extends Handler {
private Handler impl;
public SafelyHandlerWarpper(Handler impl) {
this.impl = impl;
}
@Override
public void dispatchMessage(Message msg) {
try {
super.dispatchMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void handleMessage(Message msg) {
impl.handleMessage(msg);//需要委托给原Handler执行
}
}
private static void hook(Toast toast) {
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= Build.VERSION_CODES.O) {
//8.0或以上,此异常已经被处理 以下通过反射处理
return;
}
try {
Field sField_TN = Toast.class.getDeclaredField("mTN");
sField_TN.setAccessible(true);
Field sField_TN_Handler = sField_TN.getType().getDeclaredField("mHandler");
sField_TN_Handler.setAccessible(true);
Object tn = sField_TN.get(toast);
Handler preHandler = (Handler) sField_TN_Handler.get(tn);
sField_TN_Handler.set(tn, new SafelyHandlerWarpper(preHandler));
} catch (Exception e) {
}
}
}