添加日志,文件,BaseBean类,未调试。
This commit is contained in:
		@@ -7,6 +7,10 @@
 | 
			
		||||
            android:name=".CrashHandler$CrashActiviy"
 | 
			
		||||
            android:label="CrashActiviy"
 | 
			
		||||
            android:launchMode="standard"/>
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".CrashHandler$GlobalCrashActiviy"
 | 
			
		||||
            android:label="GlobalCrashActiviy"
 | 
			
		||||
            android:launchMode="standard"/>
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,283 @@
 | 
			
		||||
package cc.winboll.studio.libappbase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author ZhanGSKen@QQ.COM
 | 
			
		||||
 * @Date 2025/01/15 11:11:52
 | 
			
		||||
 * @Describe Json Bean 基础类。
 | 
			
		||||
 */
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.util.JsonReader;
 | 
			
		||||
import android.util.JsonWriter;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.StringReader;
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public abstract class BaseBean<T extends BaseBean> {
 | 
			
		||||
 | 
			
		||||
    public static final String TAG = "BaseBean";
 | 
			
		||||
    static final String BEAN_NAME = "BeanName";
 | 
			
		||||
 | 
			
		||||
    public BaseBean() {}
 | 
			
		||||
 | 
			
		||||
    public abstract String getName();
 | 
			
		||||
 | 
			
		||||
    public String getBeanJsonFilePath(Context context) {
 | 
			
		||||
 | 
			
		||||
        return context.getExternalFilesDir(TAG) + "/" + getName() + ".json";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getBeanListJsonFilePath(Context context) {
 | 
			
		||||
 | 
			
		||||
        return context.getExternalFilesDir(TAG) + "/" + getName() + "_List.json";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
 | 
			
		||||
        jsonWriter.name(BEAN_NAME).value(getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract public T readBeanFromJsonReader(JsonReader jsonReader) throws IOException;
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> String checkIsTheSameBeanListAndFile(String szFilePath, Class<T> clazz) {
 | 
			
		||||
        StringBuilder sbResult = new StringBuilder();
 | 
			
		||||
        String szErrorInfo = "Check Is The Same Bean List And File Error : ";
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            int nSameCount = 0;
 | 
			
		||||
            int nBeanListCout = 0;
 | 
			
		||||
 | 
			
		||||
            T beanTemp = clazz.newInstance();
 | 
			
		||||
            String szBeanSimpleName = beanTemp.getName();
 | 
			
		||||
            String szListJson = FileUtils.readStringFromFile(szFilePath);
 | 
			
		||||
            StringReader stringReader = new StringReader(szListJson);
 | 
			
		||||
            JsonReader jsonReader = new JsonReader(stringReader);
 | 
			
		||||
            jsonReader.beginArray();
 | 
			
		||||
            while (jsonReader.hasNext()) {
 | 
			
		||||
                nBeanListCout++;
 | 
			
		||||
                jsonReader.beginObject();
 | 
			
		||||
                while (jsonReader.hasNext()) {
 | 
			
		||||
                    String name = jsonReader.nextName();
 | 
			
		||||
                    if (name.equals(BEAN_NAME)) {
 | 
			
		||||
                        if (szBeanSimpleName.equals(jsonReader.nextString())) {
 | 
			
		||||
                            nSameCount++;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        jsonReader.skipValue();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                jsonReader.endObject();
 | 
			
		||||
            }
 | 
			
		||||
            jsonReader.endArray();
 | 
			
		||||
 | 
			
		||||
            // 返回检查结果
 | 
			
		||||
            if (nSameCount == nBeanListCout) {
 | 
			
		||||
                // 检查一致直接返回空串
 | 
			
		||||
                return "";
 | 
			
		||||
            } else {
 | 
			
		||||
                // 检查不一致返回对比信息
 | 
			
		||||
                sbResult.append("Total : ");
 | 
			
		||||
                sbResult.append(nBeanListCout);
 | 
			
		||||
                sbResult.append(" Diff : ");
 | 
			
		||||
                sbResult.append(nBeanListCout - nSameCount);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (InstantiationException e) {
 | 
			
		||||
            sbResult.append(szErrorInfo);
 | 
			
		||||
            sbResult.append(e);
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            sbResult.append(szErrorInfo);
 | 
			
		||||
            sbResult.append(e);
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            sbResult.append(szErrorInfo);
 | 
			
		||||
            sbResult.append(e);
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return sbResult.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> T parseStringToBean(String szBean, Class<T> clazz) throws IOException {
 | 
			
		||||
        // 创建 JsonWriter 对象
 | 
			
		||||
        StringReader stringReader = new StringReader(szBean);
 | 
			
		||||
        JsonReader jsonReader = new JsonReader(stringReader);
 | 
			
		||||
        try {
 | 
			
		||||
            T beanTemp = clazz.newInstance();
 | 
			
		||||
            return (T)beanTemp.readBeanFromJsonReader(jsonReader);
 | 
			
		||||
        } catch (InstantiationException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean parseStringToBeanList(String szBeanList, ArrayList<T> beanList, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            beanList.clear();
 | 
			
		||||
            StringReader stringReader = new StringReader(szBeanList);
 | 
			
		||||
            JsonReader jsonReader = new JsonReader(stringReader);
 | 
			
		||||
            jsonReader.beginArray();
 | 
			
		||||
            while (jsonReader.hasNext()) {
 | 
			
		||||
                T beanTemp = clazz.newInstance();
 | 
			
		||||
                T bean = (T)beanTemp.readBeanFromJsonReader(jsonReader);
 | 
			
		||||
                if (bean != null) {
 | 
			
		||||
                    beanList.add(bean);
 | 
			
		||||
                    //LogUtils.d(TAG, "beanList.add(bean)");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            jsonReader.endArray();
 | 
			
		||||
            return true;
 | 
			
		||||
            //LogUtils.d(TAG, "beanList.size() is " + Integer.toString(beanList.size()));
 | 
			
		||||
        } catch (InstantiationException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        // 创建 JsonWriter 对象
 | 
			
		||||
        StringWriter stringWriter = new StringWriter();
 | 
			
		||||
        JsonWriter jsonWriter = new JsonWriter(stringWriter);
 | 
			
		||||
        jsonWriter.setIndent("  ");
 | 
			
		||||
        try {// 开始 JSON 对象
 | 
			
		||||
            jsonWriter.beginObject();
 | 
			
		||||
            // 写入键值对
 | 
			
		||||
            writeThisToJsonWriter(jsonWriter);
 | 
			
		||||
            // 结束 JSON 对象
 | 
			
		||||
            jsonWriter.endObject();
 | 
			
		||||
            return stringWriter.toString();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        // 获取 JSON 字符串
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> String toStringByBeanList(ArrayList<T> beanList) {
 | 
			
		||||
        try {
 | 
			
		||||
            StringWriter stringWriter = new StringWriter();
 | 
			
		||||
            JsonWriter jsonWriter = new JsonWriter(stringWriter);
 | 
			
		||||
            jsonWriter.setIndent("  ");
 | 
			
		||||
            jsonWriter.beginArray();
 | 
			
		||||
            for (int i = 0; i < beanList.size(); i++) {
 | 
			
		||||
                // 开始 JSON 对象
 | 
			
		||||
                jsonWriter.beginObject();
 | 
			
		||||
                // 写入键值对
 | 
			
		||||
                beanList.get(i).writeThisToJsonWriter(jsonWriter);
 | 
			
		||||
                // 结束 JSON 对象
 | 
			
		||||
                jsonWriter.endObject();
 | 
			
		||||
            }
 | 
			
		||||
            jsonWriter.endArray();
 | 
			
		||||
            jsonWriter.close();
 | 
			
		||||
            return stringWriter.toString();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> T loadBean(Context context, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            T beanTemp = clazz.newInstance();
 | 
			
		||||
            return loadBeanFromFile(beanTemp.getBeanJsonFilePath(context), clazz);
 | 
			
		||||
        } catch (InstantiationException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> T loadBeanFromFile(String szFilePath, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            try {
 | 
			
		||||
                File fTemp = new File(szFilePath);
 | 
			
		||||
                if (fTemp.exists()) {
 | 
			
		||||
                    T beanTemp = clazz.newInstance();String szJson = FileUtils.readStringFromFile(szFilePath);
 | 
			
		||||
                    return beanTemp.parseStringToBean(szJson, clazz);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (InstantiationException e) {
 | 
			
		||||
                LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
            } catch (IllegalAccessException e) {
 | 
			
		||||
                LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean saveBean(Context context, T bean) {
 | 
			
		||||
        return saveBeanToFile(bean.getBeanJsonFilePath(context), bean);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean saveBeanToFile(String szFilePath, T bean) {
 | 
			
		||||
        try {
 | 
			
		||||
            String szJson = bean.toString();
 | 
			
		||||
            FileUtils.writeStringToFile(szFilePath, szJson);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean loadBeanList(Context context, ArrayList<T> beanListDst, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            T beanTemp = clazz.newInstance();
 | 
			
		||||
            return loadBeanListFromFile(beanTemp.getBeanListJsonFilePath(context), beanListDst, clazz);
 | 
			
		||||
        } catch (InstantiationException e) {} catch (IllegalAccessException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean loadBeanListFromFile(String szFilePath, ArrayList<T> beanList, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            File fTemp = new File(szFilePath);
 | 
			
		||||
            if (fTemp.exists()) {
 | 
			
		||||
                String szListJson = FileUtils.readStringFromFile(szFilePath);
 | 
			
		||||
                return parseStringToBeanList(szListJson, beanList, clazz);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean saveBeanList(Context context, ArrayList<T> beanList, Class<T> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            T beanTemp = clazz.newInstance();
 | 
			
		||||
            return saveBeanListToFile(beanTemp.getBeanListJsonFilePath(context), beanList);
 | 
			
		||||
        } catch (InstantiationException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends BaseBean> boolean saveBeanListToFile(String szFilePath, ArrayList<T> beanList) {
 | 
			
		||||
        try {
 | 
			
		||||
            String szJson = toStringByBeanList(beanList);
 | 
			
		||||
            FileUtils.writeStringToFile(szFilePath, szJson);
 | 
			
		||||
            //LogUtils.d(TAG, "FileUtil.writeFile beanList.size() is " + Integer.toString(beanList.size()));
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -18,17 +18,24 @@ import android.content.res.Resources;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.os.Looper;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.HorizontalScrollView;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.ScrollView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import cc.winboll.studio.libappbase.GlobalApplication;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.ObjectInputStream;
 | 
			
		||||
import java.io.ObjectOutputStream;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.lang.Thread.UncaughtExceptionHandler;
 | 
			
		||||
@@ -37,11 +44,22 @@ import java.util.Date;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
public final class CrashHandler {
 | 
			
		||||
    public static final String TAG = "CrashHandler";
 | 
			
		||||
    
 | 
			
		||||
    final static String PREFS = CrashHandler.class.getName() + "PREFS";
 | 
			
		||||
    final static String PREFS_CRASHHANDLER_ISCRASHHAPPEN = "PREFS_CRASHHANDLER_ISCRASHHAPPEN";
 | 
			
		||||
 | 
			
		||||
    public static String _CrashCountFilePath;
 | 
			
		||||
 | 
			
		||||
    public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static void init(Application app) {
 | 
			
		||||
        _CrashCountFilePath = app.getExternalFilesDir("CrashHandler") + "/IsCrashHandlerCrashHappen.dat";
 | 
			
		||||
        init(app, null);
 | 
			
		||||
        LogUtils.d(TAG, "init");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void init(final Application app, final String crashDir) {
 | 
			
		||||
@@ -90,6 +108,7 @@ public final class CrashHandler {
 | 
			
		||||
                    sb.append("App VersionName                      : ").append(versionName).append("\n");
 | 
			
		||||
                    sb.append("App VersionCode                      : ").append(versionCode).append("\n");
 | 
			
		||||
                    sb.append("AppBase GlobalApplication Debug Mode : ").append(GlobalApplication.isDebuging).append("\n");
 | 
			
		||||
                    sb.append("CrashHandler CurrentSafeLevel        : ").append(String.format("%d", AppCrashSafetyWire.getInstance().getCurrentSafetyLevel())).append("\n");
 | 
			
		||||
                    sb.append("************* Crash Head ****************\n");
 | 
			
		||||
                    sb.append("\n").append(fullStackTrace);
 | 
			
		||||
 | 
			
		||||
@@ -100,12 +119,31 @@ public final class CrashHandler {
 | 
			
		||||
                    } catch (IOException ignored) {}
 | 
			
		||||
 | 
			
		||||
                    gotoCrashActiviy: {
 | 
			
		||||
                        Intent intent = new Intent(app, CrashActiviy.class);
 | 
			
		||||
                        Intent intent = new Intent();
 | 
			
		||||
 | 
			
		||||
                        if (AppCrashSafetyWire.getInstance().isAppCrashSafetyWireOK() && AppCrashSafetyWire.getInstance().postCrashSafetyWire(app)) {
 | 
			
		||||
                            AppCrashSafetyWire.getInstance().reset();
 | 
			
		||||
                            intent.setClass(app, GlobalCrashActiviy.class);
 | 
			
		||||
                            intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog);
 | 
			
		||||
                            // 如果发生了 CrashHandler 内部崩溃, 就调用基础的应用崩溃显示类
 | 
			
		||||
//                            intent.setClass(app, GlobalCrashActiviy.class);
 | 
			
		||||
//                            intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            AppCrashSafetyWire.getInstance().reset();
 | 
			
		||||
                            // 正常状态调用进阶的应用崩溃显示页
 | 
			
		||||
                            intent.setClass(app, CrashActiviy.class);
 | 
			
		||||
                            intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog);
 | 
			
		||||
                        } 
 | 
			
		||||
 | 
			
		||||
//                        intent.setClass(app, CrashActiviy.class);
 | 
			
		||||
//                        intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        intent.addFlags(
 | 
			
		||||
                            Intent.FLAG_ACTIVITY_NEW_TASK
 | 
			
		||||
                            | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
 | 
			
		||||
                        );
 | 
			
		||||
                        intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog);
 | 
			
		||||
 | 
			
		||||
                        try {
 | 
			
		||||
                            app.startActivity(intent);
 | 
			
		||||
                            android.os.Process.killProcess(android.os.Process.myPid());
 | 
			
		||||
@@ -114,6 +152,10 @@ public final class CrashHandler {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                            if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null)
 | 
			
		||||
                                DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable);
 | 
			
		||||
                        } catch (Exception e) {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                            if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null)
 | 
			
		||||
                                DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@@ -135,6 +177,113 @@ public final class CrashHandler {
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 应用崩溃保险丝
 | 
			
		||||
    //
 | 
			
		||||
    public static final class AppCrashSafetyWire {
 | 
			
		||||
 | 
			
		||||
        volatile static AppCrashSafetyWire _AppCrashSafetyWire;
 | 
			
		||||
 | 
			
		||||
        volatile int currentSafetyLevel; // 熔断值,为 0 表示熔断了。
 | 
			
		||||
        private static final int _MINI = 1;
 | 
			
		||||
        private static final int _MAX = 5;
 | 
			
		||||
 | 
			
		||||
        AppCrashSafetyWire() {
 | 
			
		||||
            currentSafetyLevel = loadCurrentSafetyLevel();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static synchronized AppCrashSafetyWire getInstance() {
 | 
			
		||||
            if (_AppCrashSafetyWire == null) {
 | 
			
		||||
                _AppCrashSafetyWire = new AppCrashSafetyWire();
 | 
			
		||||
            }
 | 
			
		||||
            return _AppCrashSafetyWire;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setCurrentSafetyLevel(int currentSafetyLevel) {
 | 
			
		||||
            this.currentSafetyLevel = currentSafetyLevel;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int getCurrentSafetyLevel() {
 | 
			
		||||
            return currentSafetyLevel;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void saveCurrentSafetyLevel(int currentSafetyLevel) {
 | 
			
		||||
            this.currentSafetyLevel = currentSafetyLevel;
 | 
			
		||||
            try {
 | 
			
		||||
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(_CrashCountFilePath));
 | 
			
		||||
                oos.writeInt(currentSafetyLevel);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int loadCurrentSafetyLevel() {
 | 
			
		||||
            try {
 | 
			
		||||
                File f = new File(_CrashCountFilePath);
 | 
			
		||||
                if (f.exists()) {
 | 
			
		||||
                    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(_CrashCountFilePath));
 | 
			
		||||
                    currentSafetyLevel = ois.readInt();
 | 
			
		||||
                } else {
 | 
			
		||||
                    currentSafetyLevel = _MAX;
 | 
			
		||||
                    saveCurrentSafetyLevel(currentSafetyLevel);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            return currentSafetyLevel;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean putOnSafetyWire() {
 | 
			
		||||
            // 崩溃计数进入崩溃保险值
 | 
			
		||||
            int safeLevel = loadCurrentSafetyLevel();
 | 
			
		||||
            if (isSafetyWireOK(safeLevel)) {
 | 
			
		||||
                // 如果保险丝未熔断, 就减少一次熔断值
 | 
			
		||||
                saveCurrentSafetyLevel(safeLevel - 1);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean isSafetyWireOK(int safetyLevel) {
 | 
			
		||||
            if (safetyLevel >= _MINI && safetyLevel <= _MAX) {
 | 
			
		||||
                // 如果在保险值之内
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void reset() {
 | 
			
		||||
            saveCurrentSafetyLevel(_MAX);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void off() {
 | 
			
		||||
            saveCurrentSafetyLevel(_MINI);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean isAppCrashSafetyWireOK() {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 调用函数以启用持续崩溃保险,从而调用 CrashHandler 内部崩溃处理窗口
 | 
			
		||||
        boolean postCrashSafetyWire(final Context context) {
 | 
			
		||||
            if (AppCrashSafetyWire.getInstance().putOnSafetyWire()) {
 | 
			
		||||
                // 设置内部崩溃处理模块失效
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            // 进程持续运行时重置保险丝
 | 
			
		||||
                            //AppCrashSafetyWire.getInstance().reset();
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 1000);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class CrashActiviy extends Activity implements MenuItem.OnMenuItemClickListener {
 | 
			
		||||
 | 
			
		||||
        private static final String EXTRA_CRASH_INFO = "crashInfo";
 | 
			
		||||
@@ -147,11 +296,13 @@ public final class CrashHandler {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
            super.onCreate(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
            mLog = getIntent().getStringExtra(EXTRA_CRASH_INFO);
 | 
			
		||||
            setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
 | 
			
		||||
            setContentView: {
 | 
			
		||||
                ScrollView contentView = new ScrollView(this);
 | 
			
		||||
                contentView.setFillViewport(true);
 | 
			
		||||
 | 
			
		||||
                HorizontalScrollView hw = new HorizontalScrollView(this);
 | 
			
		||||
                hw.setBackgroundColor(Color.GRAY);
 | 
			
		||||
                TextView message = new TextView(this); {
 | 
			
		||||
@@ -161,6 +312,7 @@ public final class CrashHandler {
 | 
			
		||||
                    message.setTextIsSelectable(true);
 | 
			
		||||
                }
 | 
			
		||||
                hw.addView(message);
 | 
			
		||||
 | 
			
		||||
                contentView.addView(hw, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
 | 
			
		||||
                setContentView(contentView);
 | 
			
		||||
            }
 | 
			
		||||
@@ -215,5 +367,99 @@ public final class CrashHandler {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class GlobalCrashActiviy extends Activity implements MenuItem.OnMenuItemClickListener {
 | 
			
		||||
 | 
			
		||||
        private static final String EXTRA_CRASH_INFO = "crashInfo";
 | 
			
		||||
 | 
			
		||||
        private static final int MENUITEM_COPY = 0;
 | 
			
		||||
        private static final int MENUITEM_RESTART = 1;
 | 
			
		||||
 | 
			
		||||
        private String mLog;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
            super.onCreate(savedInstanceState);
 | 
			
		||||
            mLog = getIntent().getStringExtra(EXTRA_CRASH_INFO);
 | 
			
		||||
            setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
 | 
			
		||||
            setContentView: {
 | 
			
		||||
                ScrollView contentView = new ScrollView(this);
 | 
			
		||||
                contentView.setFillViewport(true);
 | 
			
		||||
 | 
			
		||||
                LinearLayout llTitle = new LinearLayout(this);
 | 
			
		||||
                TextView title = new TextView(this); {
 | 
			
		||||
                    int padding = dp2px(16);
 | 
			
		||||
                    title.setPadding(padding, padding, padding, padding);
 | 
			
		||||
                    title.setText("GlobalCrashActiviy");
 | 
			
		||||
                }
 | 
			
		||||
                llTitle.addView(title, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
 | 
			
		||||
                contentView.addView(llTitle, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
 | 
			
		||||
 | 
			
		||||
                HorizontalScrollView hw = new HorizontalScrollView(this);
 | 
			
		||||
                hw.setBackgroundColor(Color.GRAY);
 | 
			
		||||
                TextView message = new TextView(this); {
 | 
			
		||||
                    int padding = dp2px(16);
 | 
			
		||||
                    message.setPadding(padding, padding, padding, padding);
 | 
			
		||||
                    message.setText(mLog);
 | 
			
		||||
                    message.setTextIsSelectable(true);
 | 
			
		||||
                }
 | 
			
		||||
                hw.addView(message);
 | 
			
		||||
 | 
			
		||||
                contentView.addView(hw, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
 | 
			
		||||
                setContentView(contentView);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onBackPressed() {
 | 
			
		||||
            restart();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void restart() {
 | 
			
		||||
            PackageManager pm = getPackageManager();
 | 
			
		||||
            Intent intent = pm.getLaunchIntentForPackage(getPackageName());
 | 
			
		||||
            if (intent != null) {
 | 
			
		||||
                intent.addFlags(
 | 
			
		||||
                    Intent.FLAG_ACTIVITY_NEW_TASK
 | 
			
		||||
                    | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
 | 
			
		||||
                );
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
            finish();
 | 
			
		||||
            android.os.Process.killProcess(android.os.Process.myPid());
 | 
			
		||||
            System.exit(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private int dp2px(final float dpValue) {
 | 
			
		||||
            final float scale = Resources.getSystem().getDisplayMetrics().density;
 | 
			
		||||
            return (int) (dpValue * scale + 0.5f);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean onMenuItemClick(MenuItem item) {
 | 
			
		||||
            switch (item.getItemId()) {
 | 
			
		||||
                case MENUITEM_COPY: 
 | 
			
		||||
                    ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
 | 
			
		||||
                    cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog));
 | 
			
		||||
                    Toast.makeText(getApplication(), "The text is copied.", Toast.LENGTH_SHORT).show();
 | 
			
		||||
                    break;
 | 
			
		||||
                case MENUITEM_RESTART: 
 | 
			
		||||
                    restart();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
            menu.add(0, MENUITEM_COPY, 0, "Copy").setOnMenuItemClickListener(this)
 | 
			
		||||
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
 | 
			
		||||
            menu.add(0, MENUITEM_RESTART, 0, "Restart").setOnMenuItemClickListener(this)
 | 
			
		||||
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,120 @@
 | 
			
		||||
package cc.winboll.studio.libappbase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author ZhanGSKen@QQ.COM
 | 
			
		||||
 * @Date 2024/07/19 14:30:57
 | 
			
		||||
 * @Describe 文件工具类
 | 
			
		||||
 */
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.res.AssetManager;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.OutputStreamWriter;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.nio.file.Paths;
 | 
			
		||||
 | 
			
		||||
public class FileUtils {
 | 
			
		||||
 | 
			
		||||
    public static final String TAG = "FileUtils";
 | 
			
		||||
 | 
			
		||||
    public static void copyAssetsToSD(Context context, String szSrcAssets, String szDstSD) {
 | 
			
		||||
        LogUtils.d(TAG, "copyAssetsToSD [" + szSrcAssets + "] to [" + szDstSD + "]");
 | 
			
		||||
        AssetManager assetManager = context.getAssets();
 | 
			
		||||
        InputStream inputStream = null;
 | 
			
		||||
        OutputStream outputStream = null;
 | 
			
		||||
        try {
 | 
			
		||||
            inputStream = assetManager.open(szSrcAssets);
 | 
			
		||||
            File outputFile = new File(szDstSD);
 | 
			
		||||
            outputStream = new FileOutputStream(outputFile);
 | 
			
		||||
            byte[] buffer = new byte[1024];
 | 
			
		||||
            int length = 0;
 | 
			
		||||
            while ((length = inputStream.read(buffer)) > 0) {
 | 
			
		||||
                outputStream.write(buffer, 0, length);
 | 
			
		||||
            }
 | 
			
		||||
            outputStream.flush();
 | 
			
		||||
            LogUtils.d(TAG, "copyAssetsToSD done.");
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (inputStream != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    inputStream.close();
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (outputStream != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    outputStream.close();
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 把字符串写入文件,指定 UTF-8 编码
 | 
			
		||||
    //
 | 
			
		||||
    public static void writeStringToFile(String szFilePath, String szContent) throws IOException {
 | 
			
		||||
        File file = new File(szFilePath);
 | 
			
		||||
        if (!file.getParentFile().exists()) {
 | 
			
		||||
            file.getParentFile().mkdirs();
 | 
			
		||||
        }
 | 
			
		||||
        FileOutputStream outputStream = new FileOutputStream(file);
 | 
			
		||||
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
 | 
			
		||||
        writer.write(szContent);
 | 
			
		||||
        writer.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 读取文件到字符串,指定 UTF-8 编码
 | 
			
		||||
    //
 | 
			
		||||
    public static String readStringFromFile(String szFilePath) throws IOException {
 | 
			
		||||
        File file = new File(szFilePath);
 | 
			
		||||
        FileInputStream inputStream = new FileInputStream(file);
 | 
			
		||||
        InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
 | 
			
		||||
        StringBuilder content = new StringBuilder();
 | 
			
		||||
        int character;
 | 
			
		||||
        while ((character = reader.read()) != -1) {
 | 
			
		||||
            content.append((char) character);
 | 
			
		||||
        }
 | 
			
		||||
        reader.close();
 | 
			
		||||
        return content.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean copyFile(File srcFile, File dstFile) {
 | 
			
		||||
        if (!srcFile.exists()) {
 | 
			
		||||
            LogUtils.d(TAG, "The original file does not exist.");
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                // 源文件路径
 | 
			
		||||
                Path sourcePath = Paths.get(srcFile.getPath());
 | 
			
		||||
                // 目标文件路径
 | 
			
		||||
                Path destPath = Paths.get(dstFile.getPath());
 | 
			
		||||
                // 建立目标父级文件夹
 | 
			
		||||
                if (!dstFile.getParentFile().exists()) {
 | 
			
		||||
                    dstFile.getParentFile().mkdirs();
 | 
			
		||||
                }
 | 
			
		||||
                // 删除旧的目标文件
 | 
			
		||||
                if (dstFile.exists()) {
 | 
			
		||||
                    dstFile.delete();
 | 
			
		||||
                }
 | 
			
		||||
                // 拷贝文件
 | 
			
		||||
                Files.copy(sourcePath, destPath);
 | 
			
		||||
                LogUtils.d(TAG, "File copy successfully.");
 | 
			
		||||
                return true;
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -20,10 +20,13 @@ import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
public class GlobalApplication extends Application {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public static final String TAG = "GlobalApplication";
 | 
			
		||||
    
 | 
			
		||||
    final static String PREFS = GlobalApplication.class.getName() + "PREFS";
 | 
			
		||||
    final static String PREFS_ISDEBUGING = "PREFS_ISDEBUGING";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
 | 
			
		||||
 | 
			
		||||
    // 是否处于调试状态
 | 
			
		||||
@@ -57,13 +60,15 @@ public class GlobalApplication extends Application {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate() {
 | 
			
		||||
        super.onCreate();
 | 
			
		||||
 | 
			
		||||
        // 设置应用异常处理窗口
 | 
			
		||||
        CrashHandler.init(this);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // 设置应用调试状态
 | 
			
		||||
        SharedPreferences sharedPreferences = getSharedPreferences(PREFS, Context.MODE_PRIVATE);
 | 
			
		||||
        GlobalApplication.isDebuging = sharedPreferences.getBoolean(PREFS_ISDEBUGING, GlobalApplication.isDebuging);
 | 
			
		||||
 | 
			
		||||
        LogUtils.init(this);
 | 
			
		||||
        LogUtils.d(TAG, "onCreate");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void write(InputStream input, OutputStream output) throws IOException {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,369 @@
 | 
			
		||||
package cc.winboll.studio.libappbase;
 | 
			
		||||
/**
 | 
			
		||||
 * @Author ZhanGSKen@QQ.COM
 | 
			
		||||
 * @Date 2024/08/12 13:44:06
 | 
			
		||||
 * @Describe LogUtils
 | 
			
		||||
 * @Describe 应用日志类
 | 
			
		||||
 */
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import cc.winboll.studio.libappbase.GlobalApplication;
 | 
			
		||||
import dalvik.system.DexFile;
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.BufferedWriter;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.io.OutputStreamWriter;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class LogUtils {
 | 
			
		||||
 | 
			
		||||
    public static final String TAG = "LogUtils";
 | 
			
		||||
 | 
			
		||||
    public static enum LOG_LEVEL { Off, Error, Warn, Info, Debug, Verbose }
 | 
			
		||||
 | 
			
		||||
    static volatile boolean _IsInited = false;
 | 
			
		||||
    static Context _mContext;
 | 
			
		||||
    // 日志显示时间格式
 | 
			
		||||
    static SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("[yyyyMMdd_HHmmSS]", Locale.getDefault());
 | 
			
		||||
    // 应用日志文件夹
 | 
			
		||||
    static File _mfLogCacheDir;
 | 
			
		||||
    static File _mfLogDataDir;
 | 
			
		||||
    // 应用日志文件
 | 
			
		||||
    static File _mfLogCatchFile;
 | 
			
		||||
    static File _mfLogUtilsBeanFile;
 | 
			
		||||
    static LogUtilsBean _mLogUtilsBean;
 | 
			
		||||
    public static Map<String, Boolean> mapTAGList = new HashMap<String, Boolean>();
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 初始化函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void init(Context context) {
 | 
			
		||||
        _mContext = context;
 | 
			
		||||
        init(context, LOG_LEVEL.Off);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 初始化函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void init(Context context, LOG_LEVEL logLevel) {
 | 
			
		||||
        if (GlobalApplication.isDebuging()) {
 | 
			
		||||
            // 初始化日志缓存文件路径
 | 
			
		||||
            _mfLogCacheDir = new File(context.getApplicationContext().getExternalCacheDir(), TAG);
 | 
			
		||||
            if (!_mfLogCacheDir.exists()) {
 | 
			
		||||
                _mfLogCacheDir.mkdirs();
 | 
			
		||||
            }
 | 
			
		||||
            _mfLogCatchFile = new File(_mfLogCacheDir, "log.txt");
 | 
			
		||||
 | 
			
		||||
            // 初始化日志配置文件路径
 | 
			
		||||
            _mfLogDataDir = context.getApplicationContext().getExternalFilesDir(TAG);
 | 
			
		||||
            if (!_mfLogDataDir.exists()) {
 | 
			
		||||
                _mfLogDataDir.mkdirs();
 | 
			
		||||
            }
 | 
			
		||||
            _mfLogUtilsBeanFile = new File(_mfLogDataDir, TAG + ".json");
 | 
			
		||||
        } else {
 | 
			
		||||
            // 初始化日志缓存文件路径
 | 
			
		||||
            _mfLogCacheDir = new File(context.getApplicationContext().getCacheDir(), TAG);
 | 
			
		||||
            if (!_mfLogCacheDir.exists()) {
 | 
			
		||||
                _mfLogCacheDir.mkdirs();
 | 
			
		||||
            }
 | 
			
		||||
            _mfLogCatchFile = new File(_mfLogCacheDir, "log.txt");
 | 
			
		||||
 | 
			
		||||
            // 初始化日志配置文件路径
 | 
			
		||||
            _mfLogDataDir = new File(context.getApplicationContext().getFilesDir(), TAG);
 | 
			
		||||
            if (!_mfLogDataDir.exists()) {
 | 
			
		||||
                _mfLogDataDir.mkdirs();
 | 
			
		||||
            }
 | 
			
		||||
            _mfLogUtilsBeanFile = new File(_mfLogDataDir, TAG + ".json");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
//        Toast.makeText(context,
 | 
			
		||||
//                       "_mfLogUtilsBeanFile : " + _mfLogUtilsBeanFile
 | 
			
		||||
//                       + "\n_mfLogCatchFile : " + _mfLogCatchFile,
 | 
			
		||||
//                       Toast.LENGTH_SHORT).show();
 | 
			
		||||
//
 | 
			
		||||
        _mLogUtilsBean = LogUtilsBean.loadBeanFromFile(_mfLogUtilsBeanFile.getPath(), LogUtilsBean.class);
 | 
			
		||||
        if (_mLogUtilsBean == null) {
 | 
			
		||||
            _mLogUtilsBean = new LogUtilsBean();
 | 
			
		||||
            _mLogUtilsBean.saveBeanToFile(_mfLogUtilsBeanFile.getPath(), _mLogUtilsBean);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 加载当前应用下的所有类的 TAG
 | 
			
		||||
        addClassTAGList();
 | 
			
		||||
        loadTAGBeanSettings();
 | 
			
		||||
        _IsInited = true;
 | 
			
		||||
        LogUtils.d(TAG, String.format("mapTAGList : %s", mapTAGList.toString()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Map<String, Boolean> getMapTAGList() {
 | 
			
		||||
        return mapTAGList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void loadTAGBeanSettings() {
 | 
			
		||||
        ArrayList<LogUtilsClassTAGBean> list = new ArrayList<LogUtilsClassTAGBean>();
 | 
			
		||||
        LogUtilsClassTAGBean.loadBeanList(_mContext, list, LogUtilsClassTAGBean.class);
 | 
			
		||||
        for (int i = 0; i < list.size(); i++) {
 | 
			
		||||
            LogUtilsClassTAGBean beanSetting = list.get(i);
 | 
			
		||||
            for (Map.Entry<String, Boolean> entry : mapTAGList.entrySet()) {
 | 
			
		||||
                if (entry.getKey().equals(beanSetting.getTag())) {
 | 
			
		||||
                    entry.setValue(beanSetting.getEnable());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void saveTAGBeanSettings() {
 | 
			
		||||
        ArrayList<LogUtilsClassTAGBean> list = new ArrayList<LogUtilsClassTAGBean>();
 | 
			
		||||
        for (Map.Entry<String, Boolean> entry : mapTAGList.entrySet()) {
 | 
			
		||||
            list.add(new LogUtilsClassTAGBean(entry.getKey(), entry.getValue()));
 | 
			
		||||
        }
 | 
			
		||||
        LogUtilsClassTAGBean.saveBeanList(_mContext, list, LogUtilsClassTAGBean.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void addClassTAGList() {
 | 
			
		||||
        //ClassLoader classLoader = getClass().getClassLoader();
 | 
			
		||||
        try {
 | 
			
		||||
            //String packageName = context.getPackageName();
 | 
			
		||||
            String packageNamePrefix = "cc.winboll.studio";
 | 
			
		||||
            List<String> classNames = new ArrayList<>();
 | 
			
		||||
            String apkPath = _mContext.getPackageCodePath();
 | 
			
		||||
            //Log.d("APK_PATH", "The APK path is: " + apkPath);
 | 
			
		||||
            LogUtils.d(TAG, String.format("apkPath : %s", apkPath));
 | 
			
		||||
            //String apkPath = "/data/app/" + packageName + "-";
 | 
			
		||||
 | 
			
		||||
            //DexFile dexfile = new DexFile(apkPath + "1/base.apk");
 | 
			
		||||
            DexFile dexfile = new DexFile(apkPath);
 | 
			
		||||
 | 
			
		||||
            int countTemp = 0;
 | 
			
		||||
            Enumeration<String> entries = dexfile.entries();
 | 
			
		||||
            while (entries.hasMoreElements()) {
 | 
			
		||||
                countTemp++;
 | 
			
		||||
                String className = entries.nextElement();
 | 
			
		||||
                if (className.startsWith(packageNamePrefix)) {
 | 
			
		||||
                    classNames.add(className);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            LogUtils.d(TAG, String.format("countTemp : %d\nClassNames size : %d", countTemp, classNames.size()));
 | 
			
		||||
 | 
			
		||||
            for (String className : classNames) {
 | 
			
		||||
                try {
 | 
			
		||||
                    Class<?> clazz = Class.forName(className);
 | 
			
		||||
                    Field[] fields = clazz.getDeclaredFields();
 | 
			
		||||
                    for (Field field : fields) {
 | 
			
		||||
                        if (Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) && field.getType() == String.class && "TAG".equals(field.getName())) {
 | 
			
		||||
                            String tagValue = (String) field.get(null);
 | 
			
		||||
                            //Log.d("TAG_INFO", "Class: " + className + ", TAG value: " + tagValue);
 | 
			
		||||
                            //LogUtils.d(TAG, String.format("Tag Value : %s", tagValue));
 | 
			
		||||
                            //mapTAGList.put(tagValue, true);
 | 
			
		||||
                            mapTAGList.put(tagValue, false);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (NoClassDefFoundError | ClassNotFoundException | IllegalAccessException e) {
 | 
			
		||||
                    LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
 | 
			
		||||
                    //LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
 | 
			
		||||
                    //Toast.makeText(context, TAG + " : " + e.getMessage(), Toast.LENGTH_SHORT).show();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
 | 
			
		||||
            //Toast.makeText(context, TAG + " : " + e.getMessage(), Toast.LENGTH_SHORT).show();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setTAGListEnable(String tag, boolean isEnable) {
 | 
			
		||||
        Iterator<Map.Entry<String, Boolean>> iterator = mapTAGList.entrySet().iterator();
 | 
			
		||||
        while (iterator.hasNext()) {
 | 
			
		||||
            Map.Entry<String, Boolean> entry = iterator.next();
 | 
			
		||||
            if (tag.equals(entry.getKey())) {
 | 
			
		||||
                entry.setValue(isEnable);
 | 
			
		||||
                //System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        saveTAGBeanSettings();
 | 
			
		||||
        LogUtils.d(TAG, String.format("mapTAGList : %s", mapTAGList.toString()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setALlTAGListEnable(boolean isEnable) {
 | 
			
		||||
        Iterator<Map.Entry<String, Boolean>> iterator = mapTAGList.entrySet().iterator();
 | 
			
		||||
        while (iterator.hasNext()) {
 | 
			
		||||
            Map.Entry<String, Boolean> entry = iterator.next();
 | 
			
		||||
            entry.setValue(isEnable);
 | 
			
		||||
            //System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
 | 
			
		||||
        }
 | 
			
		||||
        saveTAGBeanSettings();
 | 
			
		||||
        LogUtils.d(TAG, String.format("mapTAGList : %s", mapTAGList.toString()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setLogLevel(LOG_LEVEL logLevel) {
 | 
			
		||||
        LogUtils._mLogUtilsBean.setLogLevel(logLevel);
 | 
			
		||||
        _mLogUtilsBean.saveBeanToFile(_mfLogUtilsBeanFile.getPath(), _mLogUtilsBean);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static LOG_LEVEL getLogLevel() {
 | 
			
		||||
        return LogUtils._mLogUtilsBean.getLogLevel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static boolean isLoggable(String tag, LOG_LEVEL logLevel) {
 | 
			
		||||
        return _IsInited && mapTAGList.get(tag) && isInTheLevel(logLevel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static boolean isInTheLevel(LOG_LEVEL logLevel) {
 | 
			
		||||
        return (LogUtils._mLogUtilsBean.getLogLevel().ordinal() == logLevel.ordinal()
 | 
			
		||||
            || LogUtils._mLogUtilsBean.getLogLevel().ordinal() > logLevel.ordinal());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 获取应用日志文件夹
 | 
			
		||||
    //
 | 
			
		||||
    public static File getLogCacheDir() {
 | 
			
		||||
        return _mfLogCacheDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void e(String szTAG, String szMessage) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Error)) {
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Error, szMessage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void w(String szTAG, String szMessage) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Warn)) {
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Warn, szMessage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void i(String szTAG, String szMessage) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Info)) {
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Info, szMessage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void d(String szTAG, String szMessage) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Debug)) {
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Debug, szMessage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    // 包含线程调试堆栈信息
 | 
			
		||||
    //
 | 
			
		||||
    public static void d(String szTAG, String szMessage, StackTraceElement[] listStackTrace) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Debug)) {
 | 
			
		||||
            StringBuilder sbMessage = new StringBuilder(szMessage);
 | 
			
		||||
            sbMessage.append(" \nAt ");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getMethodName());
 | 
			
		||||
            sbMessage.append(" (");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getFileName());
 | 
			
		||||
            sbMessage.append(":");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getLineNumber());
 | 
			
		||||
            sbMessage.append(")");
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Debug, sbMessage.toString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    // 包含异常信息和线程调试堆栈信息
 | 
			
		||||
    //
 | 
			
		||||
    public static void d(String szTAG, Exception e, StackTraceElement[] listStackTrace) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Debug)) {
 | 
			
		||||
            StringBuilder sbMessage = new StringBuilder(e.getClass().toGenericString());
 | 
			
		||||
            sbMessage.append(" : ");
 | 
			
		||||
            sbMessage.append(e.getMessage());
 | 
			
		||||
            sbMessage.append(" \nAt ");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getMethodName());
 | 
			
		||||
            sbMessage.append(" (");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getFileName());
 | 
			
		||||
            sbMessage.append(":");
 | 
			
		||||
            sbMessage.append(listStackTrace[2].getLineNumber());
 | 
			
		||||
            sbMessage.append(")");
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Debug, sbMessage.toString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 调试日志写入函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void v(String szTAG, String szMessage) {
 | 
			
		||||
        if (isLoggable(szTAG, LogUtils.LOG_LEVEL.Verbose)) {
 | 
			
		||||
            saveLog(szTAG, LogUtils.LOG_LEVEL.Verbose, szMessage);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 日志文件保存函数
 | 
			
		||||
    //
 | 
			
		||||
    static void saveLog(String szTAG, LogUtils.LOG_LEVEL logLevel, String szMessage) {
 | 
			
		||||
        try {
 | 
			
		||||
            BufferedWriter out = null;
 | 
			
		||||
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_mfLogCatchFile, true), "UTF-8"));
 | 
			
		||||
            out.write("[" + logLevel + "]  " + mSimpleDateFormat.format(System.currentTimeMillis()) + "  [" + szTAG + "]\n" + szMessage + "\n");
 | 
			
		||||
            out.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LogUtils.d(TAG, "IOException : " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 历史日志加载函数
 | 
			
		||||
    //
 | 
			
		||||
    public static String loadLog() {
 | 
			
		||||
        if (_mfLogCatchFile.exists()) {
 | 
			
		||||
            StringBuffer sb = new StringBuffer();
 | 
			
		||||
            try {
 | 
			
		||||
                BufferedReader in = null;
 | 
			
		||||
                in = new BufferedReader(new InputStreamReader(new FileInputStream(_mfLogCatchFile), "UTF-8"));
 | 
			
		||||
                String line = "";
 | 
			
		||||
                while ((line = in.readLine()) != null) {
 | 
			
		||||
                    sb.append(line);
 | 
			
		||||
                    sb.append("\n");
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                LogUtils.d(TAG, "IOException : " + e.getMessage());
 | 
			
		||||
            } 
 | 
			
		||||
            return sb.toString();
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // 清理日志函数
 | 
			
		||||
    //
 | 
			
		||||
    public static void cleanLog() {
 | 
			
		||||
        if (_mfLogCatchFile.exists()) {
 | 
			
		||||
            try {
 | 
			
		||||
                FileUtils.writeStringToFile(_mfLogCatchFile.getPath(), "");
 | 
			
		||||
                //LogUtils.d(TAG, "cleanLog");
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,70 @@
 | 
			
		||||
package cc.winboll.studio.libappbase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author ZhanGSKen@QQ.COM
 | 
			
		||||
 * @Date 2024/08/23 15:39:07
 | 
			
		||||
 * @Describe LogUtils 数据配置类。
 | 
			
		||||
 */
 | 
			
		||||
import android.util.JsonReader;
 | 
			
		||||
import android.util.JsonWriter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
public class LogUtilsBean extends BaseBean {
 | 
			
		||||
 | 
			
		||||
    public static final String TAG = "LogUtilsBean";
 | 
			
		||||
 | 
			
		||||
    LogUtils.LOG_LEVEL logLevel;
 | 
			
		||||
 | 
			
		||||
    public LogUtilsBean() {
 | 
			
		||||
        this.logLevel = LogUtils.LOG_LEVEL.Off;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LogUtilsBean(LogUtils.LOG_LEVEL logLevel) {
 | 
			
		||||
        this.logLevel = logLevel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setLogLevel(LogUtils.LOG_LEVEL logLevel) {
 | 
			
		||||
        this.logLevel = logLevel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LogUtils.LOG_LEVEL getLogLevel() {
 | 
			
		||||
        return logLevel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return LogUtilsBean.class.getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
 | 
			
		||||
        super.writeThisToJsonWriter(jsonWriter);
 | 
			
		||||
        LogUtilsBean bean = this;
 | 
			
		||||
        jsonWriter.name("logLevel").value(bean.getLogLevel().ordinal());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
 | 
			
		||||
        if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
 | 
			
		||||
            if (name.equals("logLevel")) {
 | 
			
		||||
                setLogLevel(LogUtils.LOG_LEVEL.values()[jsonReader.nextInt()]);
 | 
			
		||||
            } else {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
 | 
			
		||||
        jsonReader.beginObject();
 | 
			
		||||
        while (jsonReader.hasNext()) {
 | 
			
		||||
            String name = jsonReader.nextName();
 | 
			
		||||
            if (!initObjectsFromJsonReader(jsonReader, name)) {
 | 
			
		||||
                jsonReader.skipValue();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // 结束 JSON 对象
 | 
			
		||||
        jsonReader.endObject();
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
package cc.winboll.studio.libappbase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author ZhanGSKen@QQ.COM
 | 
			
		||||
 * @Date 2025/01/04 14:17:02
 | 
			
		||||
 * @Describe 日志类class TAG 标签数据类
 | 
			
		||||
 */
 | 
			
		||||
import android.util.JsonReader;
 | 
			
		||||
import android.util.JsonWriter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class LogUtilsClassTAGBean extends BaseBean {
 | 
			
		||||
 | 
			
		||||
    public static final String TAG = "LogUtilsClassTAGBean";
 | 
			
		||||
 | 
			
		||||
    // 标签名
 | 
			
		||||
    String tag;
 | 
			
		||||
    // 是否启用
 | 
			
		||||
    Boolean enable;
 | 
			
		||||
 | 
			
		||||
    public LogUtilsClassTAGBean() {
 | 
			
		||||
        this.tag = TAG;
 | 
			
		||||
        this.enable = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LogUtilsClassTAGBean(String tag, Boolean enable) {
 | 
			
		||||
        this.tag = tag;
 | 
			
		||||
        this.enable = enable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTag(String tag) {
 | 
			
		||||
        this.tag = tag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTag() {
 | 
			
		||||
        return tag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setEnable(Boolean enable) {
 | 
			
		||||
        this.enable = enable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Boolean getEnable() {
 | 
			
		||||
        return enable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return LogUtilsClassTAGBean.class.getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
 | 
			
		||||
        super.writeThisToJsonWriter(jsonWriter);
 | 
			
		||||
        LogUtilsClassTAGBean bean = this;
 | 
			
		||||
        jsonWriter.name("tag").value(bean.getTag());
 | 
			
		||||
        jsonWriter.name("enable").value(bean.getEnable());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
 | 
			
		||||
        if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
 | 
			
		||||
            if (name.equals("tag")) {
 | 
			
		||||
                setTag(jsonReader.nextString());
 | 
			
		||||
            } else if (name.equals("enable")) {
 | 
			
		||||
                setEnable(jsonReader.nextBoolean());
 | 
			
		||||
            } else {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
 | 
			
		||||
        jsonReader.beginObject();
 | 
			
		||||
        while (jsonReader.hasNext()) {
 | 
			
		||||
            String name = jsonReader.nextName();
 | 
			
		||||
            if (!initObjectsFromJsonReader(jsonReader, name)) {
 | 
			
		||||
                jsonReader.skipValue();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // 结束 JSON 对象
 | 
			
		||||
        jsonReader.endObject();
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user