QT应用程序作为Android系统应用程序
QT Application as System App on Android
我正在使用QT将我们的应用程序移植到Android平台。这是一个kiosk类型的应用程序,设备是根深蒂固的,我们对它们有完全的控制。为了修改一些系统设置(特别是网络),我们的应用程序需要作为系统应用程序安装。为了完成这一点,我在adb shell中使用以下命令(在adb重新挂载之后):
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)一起位于/system/lib中。所以,libQt5Widgets。所以等)
搜索"Can't find main library"让我找到了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">
但/数据/app-lib/com.me。当my_app是一个系统应用程序时,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重启后,我的应用程序运行。
所以我的问题是什么是在包。xml中的nativeLibraryPath用于?Android似乎通过/data/data/com.me搜索图书馆。My_app/lib,它是指向/data/app-lib/com.me的符号链接。my_app-1或/system/lib取决于它是否是用户或系统应用程序。我弄清楚了这一点,因为如果我不将Qt库移动到/system/lib并更改符号链接(步骤5,7和8),我的应用程序甚至更早抛出异常,因为Android找不到Qt库。
但它似乎QT正在使用的值从包。xml的nativeLibraryPath找到我的库。将其更改为/system/lib是正确的解决方案吗?还有其他潜在的副作用吗?或者这是QT部分的不当行为,它应该使用与其他Android相同的搜索路径?
我认为正确的解决方案是从/data/app-lib/com.me重新创建符号链接。My_app-1到/system/lib。只有在将应用程序移到系统文件夹后的第一次重新启动时才会删除它,并且从重新启动和应用程序更新开始保持稳定。所以我要把这个标记为答案以防其他人遇到同样的问题。作为参考,我最终从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
您可以使用此补丁集作为临时解决方案:https://codereview.qt-project.org/194507android-build/libs/中的所有库必须部署在设备(或固件)的/system/lib文件夹
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 在不使用系统的情况下从C++应用程序格式化 Linux 中的 SD 卡
- 如何为模块化应用程序实现C++插件系统
- 设置我的应用程序 API 感知并防止系统使其模糊和错误定位
- 如何设置Qt应用程序以使用类Unix系统的实际环境变量?
- 通知 Windows 系统应用程序字体已被卸载/删除
- 即使在我为我的应用程序授予管理员后也无法从 Windows 系统复制目录
- 如何将控制台应用程序放入系统托盘通知C++?
- 适用于 macOS 的 Qt 5.9.1 的系统托盘应用程序
- 错误:尝试在全新系统安装中构建应用程序后未定义对'...'的引用
- 打开应用程序主窗口 在系统托盘图标中的其他应用程序之上
- 强制系统 QT 库使用应用程序附带的 openssl 库
- 如何监视应用程序进行的Windows系统API调用?
- 如何在应用程序正在运行的系统上查看所需的Windows API函数
- 如何在Qt中打开外部应用程序并将其最小化到系统托盘
- 将WM_CHANGEUISTATE发送到窗口应用程序后,当用鼠标访问菜单时,助记符不会显示在系统菜单上
- 如何在没有窗口类的情况下编写QT系统托盘应用程序,并将其与另一个进程集成
- 在任务管理器中修改应用程序图标,而不是在系统托盘中
- C#/C++:启动应用程序并处理其对系统的I/O调用
- 为什么非unicode应用程序系统语言环境使Unicode字体具有错误显示的符号字符