Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解决工程型代码打包的 apk 安装后无法运行的问题。 #264

Merged
merged 1 commit into from
Oct 23, 2024

Conversation

kvii
Copy link
Contributor

@kvii kvii commented Oct 16, 2024

在 vscode 或在 app 中创建的工程,在 app 打包后运行直接闪退。但是 app 里创建的单文件打包后就能正常运行。用 logcat 抓闪退 apk 的日志发现闪退原因是缺少对应的 .so 文件。

FATAL EXCEPTION: main (Ask Gemini)
Process: org.example.ttt, PID: 12260
java.lang.UnsatisfiedLinkError: dlopen failed: library "libjackpal-termexec2.so" not found
	at java.lang.Runtime.loadLibrary0(Runtime.java:1081)
	at java.lang.Runtime.loadLibrary0(Runtime.java:1003)
	at java.lang.System.loadLibrary(System.java:1765)
	at jackpal.androidterm.TermExec.<clinit>(TermExec.java:22)
	at jackpal.androidterm.ShellTermSession.createSubprocess(ShellTermSession.java:153)
	at jackpal.androidterm.ShellTermSession.initializeSession(ShellTermSession.java:101)
	at jackpal.androidterm.ShellTermSession.<init>(ShellTermSession.java:57)
	at org.autojs.autojs.runtime.api.Shell$MyShellTermSession.<init>(Shell.java:219)
	at org.autojs.autojs.runtime.api.Shell.lambda$init$0(Shell.java:100)
	at org.autojs.autojs.runtime.api.Shell.$r8$lambda$ZfzmJn7FBk93xEs5Am0lJscJHDc(Unknown Source:0)
	at org.autojs.autojs.runtime.api.Shell$$ExternalSyntheticLambda0.run(Unknown Source:4)
	at android.os.Handler.handleCallback(Handler.java:958)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loopOnce(Looper.java:205)
	at android.os.Looper.loop(Looper.java:294)
	at android.app.ActivityThread.main(ActivityThread.java:8177)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

扒拉了一下源码,发现这里应该是打包时拷贝 .so 文件的逻辑。

private fun copyLibraries(config: AppConfig) {
config.abis.forEach { abi ->
mLibsIncludes.distinct().forEach { name ->
runCatching {
File(mNativePath, "$abi/$name").copyTo(
File(workspacePath, "lib/$abi/$name"),
overwrite = true
)
}
}
}
}

然后顺着上面的函数一路找到了 AppConfig 的创建逻辑。

private ApkBuilder.AppConfig createAppConfig() {
if (mProjectConfig != null) {
return ApkBuilder.AppConfig.fromProjectConfig(mSource, mProjectConfig);
}
String jsPath = mSourcePath.getText().toString();
String versionName = mVersionName.getText().toString();
int versionCode = Integer.parseInt(mVersionCode.getText().toString());
String appName = mAppName.getText().toString();
String packageName = mPackageName.getText().toString();
ArrayList<String> abis = new ArrayList<>();
for (int i = 0; i < mFlexboxAbis.getChildCount(); i += 1) {
View child = mFlexboxAbis.getChildAt(i);
if (child instanceof RoundCheckboxWithText) {
if (((RoundCheckboxWithText) child).isChecked()) {
CharSequence charSequence = ((RoundCheckboxWithText) child).getText();
if (charSequence != null) {
abis.add(charSequence.toString());
}
}
}
}
ArrayList<String> libs = new ArrayList<>();
for (int i = 0; i < mFlexboxLibs.getChildCount(); i += 1) {
View child = mFlexboxLibs.getChildAt(i);
if (child instanceof RoundCheckboxWithText) {
if (((RoundCheckboxWithText) child).isChecked()) {
CharSequence charSequence = ((RoundCheckboxWithText) child).getText();
if (charSequence != null) {
libs.add(charSequence.toString());
}
}
}
}
return new ApkBuilder.AppConfig()
.setAppName(appName)
.setSourcePath(jsPath)
.setPackageName(packageName)
.setVersionName(versionName)
.setVersionCode(versionCode)
.setAbis(abis)
.setLibs(libs)
.setIcon(mIsDefaultIcon ? null : () -> BitmapUtils.drawableToBitmap(mIcon.getDrawable()));
}

这里 425 行有个 if 语句,个人猜测是这里的判断导致工程型的代码和文件型的代码走了不同的 AppConfig 创建逻辑。也就是说因为工程型的代码的创建逻辑缺了参数导致打包时没有复制 .so 文件。解决了这个问题后我本地运行就没有问题了。

@kvii
Copy link
Contributor Author

kvii commented Oct 17, 2024

@LZX284 对这个 PR 有什么看法吗?可以指点一下吗?

@LZX284
Copy link
Contributor

LZX284 commented Oct 19, 2024 via email

@SuperMonster003
Copy link
Owner

@kvii

此 PR 修改后的代码, 功能可用.

出现问题的原因在于, project.json 存在且可被正常解析时, ABI 设置被忽略, 导致 copyLibrariesByAbi 方法未调用, 进而 Libs.DEFALUT_INCLUDES 中包含的 "libjackpal-androidterm5.so" 和 "libjackpal-termexec2.so" 两个 so 文件未被复制 (这两个文件用于 Terminal Emulator).

此 PR 修改的代码虽然功能可用, 但考虑到上述问题的原因, 可能需要进一步处理, 包括但不限于支持 project.json 中进行 ABI 和 Libs 配置; ABI 和 Libs 配置与 project.json 需要关联; ABI 默认值应为当前设备架构而非空; Libs 默认值应为空等等.

此 PR 将被通过并进行合并, 合并后我会对相关代码做进一步处理.

@LZX284

加油, 有时我也会有一个内心的声音, 否定自己, 批评自己.

但我觉得一个人的价值不应该只取决于这些内心的声音, 每个人的努力, 善良和价值同样值得被看到, 被重视, 被珍惜.

@SuperMonster003 SuperMonster003 merged commit a7960ab into SuperMonster003:master Oct 23, 2024
1 check passed
@LZX284
Copy link
Contributor

LZX284 commented Oct 23, 2024 via email

@kvii kvii deleted the pr_project_build branch October 24, 2024 11:46
@LZX284
Copy link
Contributor

LZX284 commented Oct 25, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants