fix(cw): restore app label, fix R8 code stripping, force 32-bit ABI

Three release-breaking issues found in the v4.5.0 APK (app crashed on
launch, label showed "Morse Expert", dex shrank to 282KB vs 3.5MB):
1. app_name: the ported app_values.xml shipped a "Morse Expert"
   app_name string which overrode Look4Sat Pro's label during resource
   merging - removed (no other string collisions).
2. R8 stripped nearly all code: the in-app sun.misc.Unsafe/Cleaner
   stubs clashed with android.jar library classes. Moved stubs to
   com.rtbishop.look4sat.feature.cw.suncompat and updated k3.d/s/r
   imports (k3.r keeps the reflective Class.forName("sun.misc.Unsafe")
   string, which returns null on Android hidden-API limits).
3. proguard-rules.pro added (AGP 9 variant-level
   CanProduceConsumerProguardFiles): keep pas.** (JNI RegisterNatives
   resolves by class name) plus all ported CW classes.
4. app-level ndk abiFilters forced to armeabi-v7a: the ported
   libnativedecoderjni.so is v7a-only, so a multi-ABI APK would crash
   with UnsatisfiedLinkError on arm64 devices.

Verified: :feature:cw:compileDebugKotlin BUILD SUCCESSFUL.
This commit is contained in:
mckero committed 2026-08-04 04:56:41 +00:00
1 parent 9a54da0808
commit 544515feba
9 files changed
+57 -7

No files matched your search

+7
View File
@@ -11,6 +11,13 @@ val keystoreProperties = Properties().apply {
}
android {
// CW 解码 native 库仅 armeabi-v7a(照搬 Morse Expert 1.15): 全 ABI 打包会在
// arm64 设备 loadLibrary 失败, 强制 32 位兼容(用户设备为 32 位软件)
defaultConfig {
ndk {
abiFilters += listOf("armeabi-v7a")
}
}
signingConfigs {
if (keystoreProperties["storeFile"] != null) {
create("release") {
+13
View File
@@ -1,3 +1,6 @@
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.variant.CanProduceConsumerProguardFiles
plugins {
alias(libs.plugins.convention.featurePlugin)
}
@@ -15,6 +18,16 @@ android {
}
}
// CW 类保持规则(JNI 按类名注册 + 照搬混淆类保逻辑), 由 app 的 R8 消费
// AGP 9: consumer 规则走 variant 级 CanProduceConsumerProguardFiles
androidComponents {
onVariants(selector().all()) { variant ->
(variant as? CanProduceConsumerProguardFiles)?.consumerProguardFiles?.add(
project.layout.projectDirectory.file("proguard-rules.pro")
)
}
}
dependencies {
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
}
+31
View File
@@ -0,0 +1,31 @@
# Look4Sat Pro — CW 解码模块(照搬 Morse Expert 1.15)混淆规则
# 所有 CW 类保持原名: pas.* 通过 RegisterNatives 按类名注册 JNI(混淆即崩);
# 其余为照搬的混淆名类(命名已无混淆意义, 保持以保逻辑完整)。
# JNI 引擎(RegisterNatives 按类名/方法名查表)
-keep class pas.** { *; }
# 照搬的解码/UI 类(全部保持)
-keep class com.ve3nea.morse_expert.** { *; }
-keep class H2.** { *; }
-keep class I2.b { *; }
-keep class J2.** { *; }
-keep class k3.** { *; }
-keep class i3.** { *; }
-keep class g3.** { *; }
-keep class j3.** { *; }
-keep class s.** { *; }
-keep class d1.AbstractC1518b { *; }
-keep class B0.b { *; }
-keep class B.RunnableC0001b { *; }
-keep class D.n { *; }
-keep class E2.g { *; }
-keep class F2.a { *; }
-keep class I0.d { *; }
-keep class K1.a { *; }
-keep class j1.C1646n { *; }
# sun.misc stub(Android 无此类, 仅编译期; 防止 R8 异常处理)
-dontwarn sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class sun.misc.Cleaner { *; }
@@ -1,4 +1,4 @@
package sun.misc;
package com.rtbishop.look4sat.feature.cw.suncompat;
/**
* 编译期 stub:Android 无 sun.misc.Cleaner(照搬 Morse Expert 1.15 k3 FFT 库的清理回调,
@@ -1,4 +1,4 @@
package sun.misc;
package com.rtbishop.look4sat.feature.cw.suncompat;
/**
* 编译期 stub:Android 无 sun.misc.Unsafe(运行时通过反射获取,失败时 k3.r.f12109a 为 null)。
+1 -1
View File
@@ -1,6 +1,6 @@
package k3;
import sun.misc.Cleaner;
import com.rtbishop.look4sat.feature.cw.suncompat.Cleaner;
/* loaded from: classes.dex */
public final class d extends g {
+1 -1
View File
@@ -3,7 +3,7 @@ package k3;
import java.lang.reflect.Field;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import sun.misc.Unsafe;
import com.rtbishop.look4sat.feature.cw.suncompat.Unsafe;
/* loaded from: classes.dex */
public abstract class r {
+2 -2
View File
@@ -2,8 +2,8 @@ package k3;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import sun.misc.Cleaner;
import sun.misc.Unsafe;
import com.rtbishop.look4sat.feature.cw.suncompat.Cleaner;
import com.rtbishop.look4sat.feature.cw.suncompat.Unsafe;
/* loaded from: classes.dex */
public final class s extends g {
@@ -2,7 +2,6 @@
<resources>
<color name="purple_500">#ff6200ee</color>
<integer name="default_font_size">18</integer>
<string name="app_name">Morse Expert</string>
<string name="idle">Idle</string>
<string name="waterfall_display">Waterfall display</string>
<string name="frequency_scale">Frequency scale</string>