源码整理

This commit is contained in:
ZhanGSKen
2025-11-13 04:28:43 +08:00
parent c063175bd6
commit 8e8359aab4
3 changed files with 104 additions and 43 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Wed Nov 12 20:21:00 GMT 2025 #Wed Nov 12 20:28:00 GMT 2025
stageCount=10 stageCount=10
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.10 baseVersion=15.10
publishVersion=15.10.9 publishVersion=15.10.9
buildCount=21 buildCount=22
baseBetaVersion=15.10.10 baseBetaVersion=15.10.10

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Wed Nov 12 20:21:00 GMT 2025 #Wed Nov 12 20:28:00 GMT 2025
stageCount=10 stageCount=10
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.10 baseVersion=15.10
publishVersion=15.10.9 publishVersion=15.10.9
buildCount=21 buildCount=22
baseBetaVersion=15.10.10 baseBetaVersion=15.10.10

View File

@@ -4,77 +4,138 @@ package cc.winboll.studio.libappbase;
* @Author ZhanGSKen<zhangsken@qq.com> * @Author ZhanGSKen<zhangsken@qq.com>
* @Date 2024/08/12 14:43:50 * @Date 2024/08/12 14:43:50
* @Describe 日志视图线程类 * @Describe 日志视图线程类
* 独立线程监听日志文件目录变化(如写入、删除),触发日志视图更新,避免阻塞主线程
*/ */
import android.os.FileObserver; import android.os.FileObserver;
import cc.winboll.studio.libappbase.LogUtils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
public class LogViewThread extends Thread { public class LogViewThread extends Thread {
/** 日志标签(用于调试输出) */
public static final String TAG = "LogViewThread"; public static final String TAG = "LogViewThread";
// 线程退出标志 /** 线程退出标志volatile 保证多线程可见性,控制循环退出) */
volatile boolean isExist = false; private volatile boolean isExit = false;
// 应用日志文件监听实例 /** 日志文件目录监听实例(监听文件写入、删除事件) */
LogListener mLogListener; private LogListener mLogListener;
// 日志视图弱引用 /** 日志视图弱引用(避免持有 LogView 强引用导致内存泄漏) */
WeakReference<LogView> mwrLogView; private final WeakReference<LogView> mLogViewWeakRef;
// /**
// 构造函数 * 构造函数
// @logView : 日志显示输出视图类 * @param logView 日志显示视图实例(需通过弱引用持有,避免内存泄漏)
*/
public LogViewThread(LogView logView) { public LogViewThread(LogView logView) {
mwrLogView = new WeakReference<LogView>(logView); // 使用弱引用包装 LogView当视图销毁时可被 GC 回收
mLogViewWeakRef = new WeakReference<>(logView);
} }
public void setIsExist(boolean isExist) { /**
this.isExist = isExist; * 设置线程退出标志(触发线程停止监听并退出)
* @param exit true退出线程false继续运行默认
*/
public void setExit(boolean exit) {
this.isExit = exit;
} }
public boolean isExist() { /**
return isExist; * 获取当前线程退出状态
* @return true已标记退出false运行中
*/
public boolean isExit() {
return isExit;
} }
/**
* 线程核心逻辑:初始化文件监听并启动循环,直到收到退出标志
*/
@Override @Override
public void run() { public void run() {
String szLogDir = LogUtils.getLogCacheDir().getPath(); // 获取日志缓存目录路径(从 LogUtils 统一获取,确保路径一致性)
mLogListener = new LogListener(szLogDir); String logDirPath = LogUtils.getLogCacheDir().getPath();
LogUtils.d(TAG, "启动日志文件监听,监听目录:" + logDirPath);
// 初始化日志文件监听器(监听目标目录的文件事件)
mLogListener = new LogListener(logDirPath);
// 开始监听文件事件(非阻塞,内部通过 Native 层实现)
mLogListener.startWatching(); mLogListener.startWatching();
while (isExist() == false) {
// 循环等待退出标志(每 1 秒检查一次,降低 CPU 占用)
while (!isExit()) {
try { try {
Thread.sleep(1000); Thread.sleep(1000); // 休眠 1 秒,避免忙等
} catch (InterruptedException e) {} } catch (InterruptedException e) {
// 线程被中断时,恢复中断标志并退出循环(避免无限阻塞)
Thread.currentThread().interrupt();
LogUtils.d(TAG, "日志监听线程被中断,准备退出。" + e);
break;
}
} }
// 收到退出标志,停止监听并释放资源
mLogListener.stopWatching(); mLogListener.stopWatching();
LogUtils.d(TAG, "日志文件监听已停止,线程退出");
} }
/**
* 日志文件监听内部类(继承 FileObserver监听目录下文件变化
* 仅关注文件写入完成CLOSE_WRITE和文件删除DELETE事件
*/
private class LogListener extends FileObserver {
// /**
// 日志文件监听类 * 构造函数
// * @param path 监听的目录路径(此处为日志缓存目录)
class LogListener extends FileObserver { */
public LogListener(String path) { public LogListener(String path) {
// 父类构造:监听指定目录的所有事件(通过位掩码 ALL_EVENTS 指定)
super(path); super(path);
} }
/**
* 文件事件回调(运行在系统私有线程,非主线程)
* @param event 事件类型(通过位掩码表示,需与 ALL_EVENTS 按位与解析)
* @param path 发生事件的文件名(相对监听目录的路径)
*/
@Override @Override
public void onEvent(int event, String path) { public void onEvent(int event, String path) {
int e = event & FileObserver.ALL_EVENTS; // 解析事件类型(排除无关事件,只处理目标事件)
switch (e) { int eventType = event & FileObserver.ALL_EVENTS;
case FileObserver.CLOSE_WRITE:{
if (mwrLogView.get() != null) { switch (eventType) {
mwrLogView.get().updateLogView(); // 事件:文件写入完成(如日志写入结束并关闭文件)
} case FileObserver.CLOSE_WRITE:
break; LogUtils.d(TAG, "日志文件写入完成,文件名:" + (path != null ? path : "未知"));
} // 触发日志视图更新(需先判断 LogView 是否未被回收)
case FileObserver.DELETE:{ updateLogView();
if (mwrLogView.get() != null) { break;
mwrLogView.get().updateLogView();
} // 事件:文件被删除(如日志清理操作)
break; case FileObserver.DELETE:
} LogUtils.d(TAG, "日志文件被删除,文件名:" + (path != null ? path : "未知"));
// 触发日志视图更新(刷新视图显示空状态)
updateLogView();
break;
default:
// 忽略其他无关事件(如文件创建、访问等)
break;
}
}
/**
* 触发日志视图更新(通过弱引用获取 LogView避免内存泄漏
*/
private void updateLogView() {
// 从弱引用中获取 LogView 实例若视图已销毁get() 返回 null
LogView logView = mLogViewWeakRef.get();
if (logView != null) {
// 调用 LogView 的更新方法(需确保 updateLogView 内部处理主线程切换)
logView.updateLogView();
} else {
LogUtils.w(TAG, "LogView 已被回收,无法更新日志视图");
} }
} }
} }
} }