android+docs: debug 日志默认关闭;操作手册升级为插图版
debug 日志:DebugLog 增加总开关 enabled(默认 false),log() 直接返回、 init() 不装崩溃钩子、startFile() 不建文件。要在设备上排查时改成 true 重新构建 即可,其它代码不动。关闭后崩溃仍按安卓常规方式可见(logcat AndroidRuntime + 系统弹窗),只是不再有落在相册目录旁的 debug_*.log。 真机烟雾测试(小米 22041211AC,相机插着):出流正常、拍照成功(相册 19→20, 新增 MAG160C_20260912_153522.jpg)、崩溃 0、App 自身日志行数 0、无新日志文件。 插图版手册 docs/android_app/app_manual.md + manual_images/: - 02_markers:标记结构解剖(准星/读数/引线/描边字),真机照片放大 3 倍并标注 - 03/04:横屏 960x720 与竖屏 720x960 的真实照片 - 05/06/07:设置、分析(含底部测量面板)、相册 真机截图 - 01_live_schematic:实时界面改为**自绘示意图**,因为实时 OSD 文字按握持角度预旋转 (用户要求的可读性设计),手册拍摄时手机横放,截图里文字全是侧躺的无法阅读; 其余界面文字本就水平,直接用截图。 图由 manual_images/MakeFigures.java 生成(裁剪缩放/放大标注/示意图绘制), 界面改动后重跑即可;原始截图存为 JPEG(PNG→JPEG 省约 8MB)作为可再生输入。 .class 已加入 .gitignore。 README 阅读顺序加入操作手册、结构表更新、里程碑补记根因级修复。105 项测试全绿。
This commit is contained in:
@@ -12,8 +12,10 @@ import com.mag160c.thermal.ui.theme.Mag160cTheme
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// field-debug crash hook + log file (opened at startup so even
|
||||
// early crashes are captured; logging never throws)
|
||||
// Field-debug logging is OFF by default (see DebugLog.enabled): a shipping
|
||||
// build writes no log file and no logcat lines. Flip that flag and rebuild to
|
||||
// capture a detailed trace on a device — these two calls then behave exactly
|
||||
// as they used to.
|
||||
com.mag160c.thermal.media.DebugLog.init(applicationContext)
|
||||
com.mag160c.thermal.media.DebugLog.startFile(applicationContext)
|
||||
// enableEdgeToEdge exists since API 21 but reaches for the modern inset
|
||||
|
||||
@@ -16,8 +16,20 @@ import java.util.Locale
|
||||
|
||||
/**
|
||||
* Field-debug logger: mirrors every line to logcat AND appends it to a
|
||||
* timestamped text file next to the photos (DCIM/MAG160C), so the user can
|
||||
* hand over the file without adb (real-device bring-up, round 11).
|
||||
* timestamped text file next to the photos (DCIM/MAG160C), so a problem on the
|
||||
* user's phone can be diagnosed without adb.
|
||||
*
|
||||
* ## It is OFF by default (user decision, 2026-09-12)
|
||||
*
|
||||
* A shipping build has no business writing a log file beside the user's photos or
|
||||
* filling logcat at 15 frames per second, so [enabled] defaults to false and every
|
||||
* entry point returns immediately. To investigate something on a device, flip
|
||||
* [enabled] to true and rebuild — that is the whole procedure; the file then
|
||||
* appears exactly as it used to.
|
||||
*
|
||||
* With logging off, crashes are still reported the normal Android way (logcat
|
||||
* `AndroidRuntime` plus the system's "app keeps stopping" dialog); only the
|
||||
* convenient on-device copy is gone.
|
||||
*
|
||||
* Logging must NEVER crash the app: every sink operation is guarded, and
|
||||
* writes are capped. Sink fallback chain (scoped storage only allows media
|
||||
@@ -28,6 +40,13 @@ import java.util.Locale
|
||||
* The header line records where the file actually ended up.
|
||||
*/
|
||||
object DebugLog {
|
||||
/**
|
||||
* Master switch. OFF in shipping builds: writes nothing, to no sink.
|
||||
* Set to true (and rebuild) to capture a detailed trace on a device.
|
||||
*/
|
||||
@Volatile
|
||||
var enabled: Boolean = false
|
||||
|
||||
private val fmt = SimpleDateFormat("HH:mm:ss.SSS", Locale.ENGLISH)
|
||||
private val fileFmt = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH)
|
||||
private val lock = Any()
|
||||
@@ -38,6 +57,7 @@ object DebugLog {
|
||||
|
||||
/** Install once from MainActivity.onCreate: crash hook + app context. */
|
||||
fun init(context: Context) {
|
||||
if (!enabled) return
|
||||
synchronized(lock) {
|
||||
if (previousHandler != null) return
|
||||
previousHandler = Thread.getDefaultUncaughtExceptionHandler()
|
||||
@@ -51,6 +71,7 @@ object DebugLog {
|
||||
|
||||
/** Log one line (also to logcat as MAG160C/<tag>). Never throws. */
|
||||
fun log(tag: String, msg: String) {
|
||||
if (!enabled) return
|
||||
try {
|
||||
Log.d("MAG160C/$tag", msg)
|
||||
} catch (_: Exception) {
|
||||
@@ -80,9 +101,10 @@ object DebugLog {
|
||||
/**
|
||||
* Open a fresh debug_*.log. Called once at app start (so even startup
|
||||
* crashes are captured); never throws. Returns the display path for
|
||||
* logging. Closes any previous file.
|
||||
* logging. Closes any previous file. Does nothing when [enabled] is false.
|
||||
*/
|
||||
fun startFile(context: Context): String {
|
||||
if (!enabled) return "(debug log disabled)"
|
||||
val name = "debug_${fileFmt.format(Date())}.log"
|
||||
closeFile()
|
||||
synchronized(lock) {
|
||||
|
||||
Reference in New Issue
Block a user