我将使用QT的应用程序移植到Android平台。这是一个自助服务终端类型的应用程序,设备已植根,我们可以完全控制它们。为了修改某些系统设置(特别是网络),我们的应用程序需要作为系统应用程序安装。为此,我在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中
用Google搜索"无法找到主库"引导我使用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的符号链接,我的应用程序就会运行。
所以我现在的问题是packages.xml中的nativeLibraryPath用于什么? Android似乎通过/data/data/com.me.my_app/lib搜索库,这是/data/app-lib/com.me.my_app-1或/ system / lib的符号链接,具体取决于它&# 39; sa用户或系统应用程序。我想出了这一点,因为如果我不将Qt库移动到/ system / lib并更改符号链接(步骤5,7和8),我的应用程序会引发异常甚至更早,因为Android无法找到QT库。
但似乎QT正在使用packages.xml中的nativeLibraryPath值来查找我的库。是将它更改为/ system / lib正确的解决方案吗?还有其他潜在的副作用吗?或者这是否是QT部分的不当行为,它应该使用与Android其他部分相同的搜索路径?
答案 0 :(得分:2)
我认为正确的解决方案是在重新启动后重新创建/data/app-lib/com.me.my_app-1到/ system / lib的符号链接。它仅在将应用程序移动到系统文件夹后的第一次重新启动时删除,并且在重新启动和应用程序更新后从该点开始稳定。所以我打算将此标记为答案,以防其他人遇到同样的问题。作为参考,我最终将adT 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
答案 1 :(得分:1)
您可以将此补丁集用作临时解决方案:https://codereview.qt-project.org/194507 android-build / libs /中的所有库必须部署在设备上的/ system / lib文件夹中(或者在构建之前的固件)