android - QT 应用程序作为 Android 上的系统应用程序

标签 android c++ qt

我正在将我们使用 QT 的应用程序移植到 Android 平台。这是一个 kiosk 类型的应用程序,设备已获得 root 权限,我们可以完全控制它们。为了修改一些系统设置(特别是网络),我们的应用程序需要作为系统应用程序安装。为此,我在 adb shell 中使用了以下命令(在 adb remount 之后):

1) pm install /data/my_app.apk
2) rm /data/my_app.apk
3) cp -p /data/app/com.me.my_app-1.apk /system/app
4) rm /data/app/com.me.my_app-1.apk
5) cp -p /data/app-lib/com.me.my_app-1/* /system/lib
6) rm -rf /data/app-lib/com.me.my_app-1
7) rm /data/data/com.me.my_app/lib
8) ln -s /system/lib /data/data/com.me.my_app/lib
9) reboot

重启后,当我启动应用程序时,我会收到一个消息框:

"Your application encountered a fatal error and cannot continue."

logcat 显示以下异常和堆栈跟踪:

I/Qt      ( 1272): qt start
D/dalvikvm( 1272): No JNI_OnLoad found in /system/lib/libmy_app.so 0x411f0a08, skipping init
W/System.err( 1272): java.lang.Exception: Can't find main library 'my_app'
W/System.err( 1272):    at org.qtproject.qt5.android.QtNative.startApplication(QtNative.java:196)
W/System.err( 1272):    at org.qtproject.qt5.android.QtActivityDelegate.startApplication(QtActivityDelegate.java:635)
W/System.err( 1272):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err( 1272):    at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:252)
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:643)
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:872)
W/System.err( 1272):    at android.app.Activity.performCreate(Activity.java:5104)
W/System.err( 1272):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
W/System.err( 1272):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
W/System.err( 1272):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
W/System.err( 1272):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
W/System.err( 1272):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
W/System.err( 1272):    at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err( 1272):    at android.os.Looper.loop(Looper.java:137)
W/System.err( 1272):    at android.app.ActivityThread.main(ActivityThread.java:5041)
W/System.err( 1272):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err( 1272):    at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err( 1272):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
W/System.err( 1272):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
W/System.err( 1272):    at dalvik.system.NativeStart.main(Native Method)
W/System.err( 1272): java.lang.Exception: 
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:253)
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:643)
W/System.err( 1272):    at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:872)
W/System.err( 1272):    at android.app.Activity.performCreate(Activity.java:5104)
W/System.err( 1272):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
W/System.err( 1272):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
W/System.err( 1272):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
W/System.err( 1272):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
W/System.err( 1272):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
W/System.err( 1272):    at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err( 1272):    at android.os.Looper.loop(Looper.java:137)
W/System.err( 1272):    at android.app.ActivityThread.main(ActivityThread.java:5041)
W/System.err( 1272):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err( 1272):    at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err( 1272):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
W/System.err( 1272):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
W/System.err( 1272):    at dalvik.system.NativeStart.main(Native Method)

libmy_app.so 与所有其他 QT 库(libQt5AndroidExtras.so、libQt5Widgets.so 等)位于/system/lib

谷歌搜索“找不到主库”让我找到了 QT 源代码,但这对追踪它找不到库的原因没有帮助。

因此,如果您对正在发生的事情有任何见解,我们将不胜感激。或者,如果有更好的、完全不同的解决方案来将 QT 应用程序作为系统应用程序运行,我也愿意接受。

提前致谢!

更新

经过更多调查后,问题似乎是因为 QTNative.startApplication() 正在使用 nativeLibraryPath 寻找 libmy_app.so。 nativeLibraryPath 在/data/system/packages.xml 中定义:

<package name="com.me.my_app" codePath="/system/app/com.me.my_app-1.apk" nativeLibraryPath="/data/app-lib/com.me.my_app-1" flags="572999" ft="1471c4d74c0" it="1471c4d7c39" ut="1471c4d7c39" version="1" userId="10063">

但是当 my_app 是系统应用程序时/data/app-lib/com.me.my_app-1 不存在。我的第一个想法是因为我在将库移动到/system/lib 文件夹后在第 6 步中删除了它。但即使离开这一步,重启设备后/data/app-lib/com.me.my_app-1 也不见了。我猜是一些 Android 包管理进程清理了它。如果我在重启后创建一个从/data/app-lib/com.me.my_app-1 指向/system/lib 的符号链接(symbolic link),我的应用程序就会运行。

所以我现在的问题是 packages.xml 中的 nativeLibraryPath 有什么用? Android 似乎通过/data/data/com.me.my_app/lib 搜索库,它是/data/app-lib/com.me.my_app-1 或/system/lib 的符号链接(symbolic link),具体取决于它是用户或系统应用程序。我想通了这一点,因为如果我不将 Qt 库移动到/system/lib 并更改符号链接(symbolic link)(步骤 5、7 和 8),我的应用程序会更早地抛出异常,因为 Android 找不到 QT 库。

但 QT 似乎正在使用 packages.xml 中的 nativeLibraryPath 值来查找我的库。将其更改为/system/lib 是正确的解决方案吗?还有其他潜在的副作用吗?或者这是 QT 的不当行为,它应该使用与 Android 其余部分相同的搜索路径?

最佳答案

我认为正确的解决方案是在重启后重新创建从/data/app-lib/com.me.my_app-1 到/system/lib 的符号链接(symbolic link)。它仅在将应用程序移动到系统文件夹后的第一次重新启动时被删除,并且从那时起在重新启动和应用程序更新期间保持稳定。所以我将把它标记为答案,以防其他人遇到同样的问题。作为引用,我最终从 adb shell 安装 QT 应用程序作为系统应用程序的过程是:

1) pm install /data/my_app.apk
2) rm /data/my_app.apk
3) cp -p /data/app/com.me.my_app-1.apk /system/app
4) rm /data/app/com.me.my_app-1.apk
5) cp -p /data/app-lib/com.me.my_app-1/* /system/lib
6) rm /data/data/com.me.my_app/lib
7) ln -s /system/lib /data/data/com.me.my_app/lib
8) reboot

再次启动 adb shell 然后:

9) ln -s /system/lib /data/app-lib/com.me.my_app-1

关于android - QT 应用程序作为 Android 上的系统应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24641604/

相关文章:

c++ - CMAKE:如何安装目标的依赖项

c++ visual studio 2008 链接问题

linux - 如果通过 Synaptic 安装,Linux 中 Qt 4.7 的 ./configure 可执行文件在哪里?

c++ - 在 qt 4.5 中,是否可以在静态链接插件中拥有资源?

c++ - QFileDialog - 创建没有扩展名的文件

android - 由于 Release模式下的内存问题导致应用程序崩溃

android - 延迟弹出对话框 fragment ,直到其中的 webview 完成加载

尝试创建 GoogleCredential 时出现 java.io.FileNotFoundException

android - 是否可以在 android 中将颜色资源设为私有(private)?

c++ - 使用 qExec 创建 Qt 测试套件