【发布时间】:2017-06-09 11:51:32
【问题描述】:
我正在尝试将其latest version 4.1.2 中的HockeyApp Android SDK 集成到我们的Qt Android 应用程序中。总的来说,我对 Android 开发或 Java 知之甚少 - 也不了解任何 Qt 或 HockeyApp 内部知识。
有一些通用的official documentation 将第三方Android(即Java)库包含到Qt 项目中;但是,它提到了当前 Qt Creator 4.2.0 版本中不存在的“在部署设置中创建 AndroidManifest.xml 按钮”,因此我不确定该文档有多过时或什么部分可能仍然适用。
HockeyApp documentation 仅涵盖使用 Android Studio 的“典型 Android 开发”,他们的支持是 not supportive。
顺便说一句,集成 HockeyApp iOS SDK 只用了几个小时,主要是编写一些 Objective C 桥代码。
第 1 步:将 SDK 添加到项目中
第一种方法
我尝试按照上述文档添加解压后的HockeySDK-Android-4.1.2 文件夹和带有内容的project.properties 文件
android.library.reference.1=HockeySDK-Android-4.1.2/libs/
到项目文件夹;我还将<my project>.pro 中的ANDROID_PACKAGE_SOURCE_DIR 设置为该项目文件夹。
问题:androiddeployqt 构建步骤发出错误消息(为便于阅读而包装)
Error: <path to build folder>/android-build/HockeySDK-Android-4.1.2/libs
is not a valid project (AndroidManifest.xml not found).
但无论如何都会继续,最后失败并显示错误消息(也为可读性包装)
BUILD FAILED
/opt/Android/android-sdk-macosx/tools/ant/build.xml:573:
HockeySDK-Android-4.1.2/libs/ resolve to a path
with no project.properties file for project <path to build folder>/android-build
使用--verbose 开关运行androiddeployqt 会显着增加输出,但有用信息为零。
第二种方法
下载的 HockeyApp Android SDK 压缩包包含 - 除了一些文档 - 一个文件 libs/HockeySDK-4.1.2.aar;从this response 和this comment,我收集到AAR format 只是一个zip 存档,其中包含一个AndroidManifest.xml 文件。我将libs/HockeySDK-4.1.2.aar 解压缩到位,然后将其删除;现在构建中的第一条错误消息消失了。
问题:构建失败
BUILD FAILED
/opt/Android/android-sdk-macosx/tools/ant/build.xml:597:
The following error occurred while executing this line:
/opt/Android/android-sdk-macosx/tools/ant/build.xml:649:
The following error occurred while executing this line:
/opt/Android/android-sdk-macosx/tools/ant/build.xml:655:
<path to build folder>/android-build/HockeySDK-Android-4.1.2/libs/src does not exist.
同样,将运行中的--verbose 添加到androiddeployqt 只会增加噪音。查看提到的build.xml 位置也无济于事。
更新:
我尝试从错误消息中简单地创建丢失的文件夹;现在构建失败如下:
-dex:
[dex] input: <path to build folder>/android-build/bin/classes
[dex] input: <path to build folder>/android-build/HockeySDK-Android-4.1.2/libs/bin/classes.jar
[dex] input: <path to build folder>/android-build/libs/QtAndroid-bundled.jar
[dex] input: <path to build folder>/android-build/libs/QtAndroidBearer-bundled.jar
[dex] Pre-Dexing <path to build folder>/android-build/libs/QtAndroid-bundled.jar -> QtAndroid-bundled-a06280f40655c27b25038380a4d7f67c.jar
[dex] Pre-Dexing <path to build folder>/android-build/libs/QtAndroidBearer-bundled.jar -> QtAndroidBearer-bundled-a69fa323dbfa477411ea082423128813.jar
[dex] Converting compiled files and external libraries into <path to build folder>/android-build/bin/classes.dex...
[dx]
[dx] UNEXPECTED TOP-LEVEL EXCEPTION:
[dx] java.io.FileNotFoundException: <path to build folder>/android-build/HockeySDK-Android-4.1.2/libs/bin/classes.jar (No such file or directory)
[dx] at java.util.zip.ZipFile.open(Native Method)
[dx] at java.util.zip.ZipFile.<init>(ZipFile.java:219)
[dx] at java.util.zip.ZipFile.<init>(ZipFile.java:149)
[dx] at java.util.zip.ZipFile.<init>(ZipFile.java:163)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:244)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
[dx] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
[dx] at com.android.dx.command.dexer.Main.processOne(Main.java:677)
[dx] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:574)
[dx] at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
[dx] at com.android.dx.command.dexer.Main.run(Main.java:277)
[dx] at com.android.dx.command.dexer.Main.main(Main.java:245)
[dx] at com.android.dx.command.Main.main(Main.java:106)
[dx] 1 error; aborting
BUILD FAILED
/opt/Android/android-sdk-macosx/tools/ant/build.xml:888: The following error occurred while executing this line:
/opt/Android/android-sdk-macosx/tools/ant/build.xml:890: The following error occurred while executing this line:
/opt/Android/android-sdk-macosx/tools/ant/build.xml:902: The following error occurred while executing this line:
/opt/Android/android-sdk-macosx/tools/ant/build.xml:283: null returned: 1
我显然不能只是编造一些classes.jar 文件,而是在<path to build folder>/android-build/HockeySDK-Android-4.1.2/libs 中有一个同名的文件,所以我可以创建缺少的bin 文件夹并在其中创建一个符号链接到../classes.jar .
现在构建成功。第 1 步完成。
第二步:在项目中使用SDK
回到对应的HockeyApp documentation,我想我需要修改一些看起来类似的代码
public class YourActivity extends Activity
...
在<path to build folder>/android-build/src/org/qtproject/qt5/android/bindings/QtActivity.java的项目中,此类代码仅出现一次:
public class QtActivity extends Activity
...
该文件由androiddeployqt 工具(Qt SDK 的一部分)从 Qt SDK 内的源文件夹 $QTDIR/src/android/java 复制到那里,即我机器上的 /opt/Qt/Qt_5.7.1/5.7/android_armv7/src/android。
查看androiddeployqt 源代码,我发现无法(例如通过命令行参数)更改这些.java 文件取自的源文件夹,因此无法提供我的自己的一组文件,并让androiddeployqt 复制它。因此,为了完成这项工作,我必须扩展/修复 androiddeployqt 功能(抱歉,我不会触及该代码 - 糟糕!)或直接在其源处修改复制的文件 - 这显然会影响所有项目构建使用那个 Qt SDK 实例。
作为第三种方法,我可以尝试修补 Java 源代码 androiddeployqt 将它们复制到构建文件夹。不幸的是,这不仅使开发和构建工作流程异常痛苦; androiddeployqt“一个工具做所有事情”设计失败(见下文)也完全不可能:在项目中存在 Java 源且 .apk 包没有的构建过程中没有时间点尚未建成。我认为 androiddeployqt --no-build 参数可以实现这一点:
--no-build: Do not build the package, it is useful to just install
a package previously built.
但是这里的“构建”是指构建 Qt / Java 桥代码,而不是实际的应用程序,因此该参数对于手头的任务几乎没有用;构建失败并显示此消息 - 这本身就是一个错误,因为消息中的 .apk 文件不存在,因此 Android 包构建不成功:
Android package built successfully in 1.011 ms.
-- File: <path to build folder>/android-build//bin/QtApp-release-unsigned.apk
当然,我可以将源代码复制到其他地方,手动修补并将它们复制到最终目的地,但我认为这是我划清界限的地方。
实际上,查看androiddeployqt 源代码才是关键所在。试图让功能失调的工具发挥作用已经浪费了太多时间:
- 首先我不会评论在 C++ 中编写 构建工具 是多么聪明 - 在单个 ~3000 行
main.cpp文件中 - 我不会评论在
androiddeployqt源中硬编码src/android/java路径(和许多其他路径)的做法不是一次,而是多次次 -而不是至少准备适当(即外部)工具配置的const QString - 我不会评论违反 一个工具,一个目的 的 50 年历史的最佳实践是多么聪明 - 并复制 Qt、Android 或 Java 工具提供的大量功能,例如构建、签名、部署、安装包等。
- 但是,该工具已通过代码审查进入许多主要 Qt 版本这一事实简直令人恐惧 - 这可能是一个很好的指标,表明是时候考虑放弃 Qt 作为一项一般技术了
在我写这篇文章时,Qt 5.8.0 安装一直冻结,使一个 CPU 内核最大化 - 并且在过去约 12 小时内一直如此。我休息一下。
我的问题
有人在 Qt、Android 和 HockeyApp 上取得过成功吗?有人对这里出了什么问题有任何提示/指针/疯狂猜测吗?- 没有其他问题;我已经看够了
第 3 步:从 C++ 调用 SDK Java 代码
(由于步骤 2 中的砖墙而取消)
【问题讨论】:
标签: java android c++ qt hockeyapp