【问题标题】:How to use HockeyApp SDK with Qt on Android如何在 Android 上使用 HockeyApp SDK 和 Qt
【发布时间】: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 responsethis 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 文件,而是在&lt;path to build folder&gt;/android-build/HockeySDK-Android-4.1.2/libs 中有一个同名的文件,所以我可以创建缺少的bin 文件夹并在其中创建一个符号链接到../classes.jar .

现在构建成功。第 1 步完成。

第二步:在项目中使用SDK

回到对应的HockeyApp documentation,我想我需要修改一些看起来类似的代码

public class YourActivity extends Activity
  ...

&lt;path to build folder&gt;/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


    【解决方案1】:

    回答我自己的问题:

    如果不修补 Qt SDK 工具源代码或 Qt SDK Java 模板源文件,则无法在 Android 上将 HockeyApp SDK 与 Qt 一起使用。

    事实上,据我所知,如果需要修改 Java 源代码,任何第三方库都无法在 Android 上与 Qt 一起使用。

    【讨论】:

      【解决方案2】:

      FWIW 这是我用于应用程序的AndroidManifest.xml,但没有外部库依赖项。您可以尝试添加+修改它以使部署工作?

      文件结构:

      /my-project-dir
      ├── android
      │   ├── AndroidManifest.xml
      │   └── res
      │       └── drawable-mdpi
      │           └── icon.png
      ├── my-project.pro
      

      AndroidManifest.xml:

      <?xml version="1.0"?>
      <manifest package="my_package_name" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
          <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="my_app_name" android:icon="@drawable/icon">
              <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="my_app_name" android:screenOrientation="unspecified" android:launchMode="singleTop">
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN"/>
                      <category android:name="android.intent.category.LAUNCHER"/>
                  </intent-filter>
                  <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                  <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                  <meta-data android:name="android.app.repository" android:value="default"/>
                  <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                  <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                  <!-- Deploy Qt libs as part of package -->
                  <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                  <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
                  <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
                  <!-- Run with local libs -->
                  <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                  <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                  <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
                  <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                  <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                  <!--  Messages maps -->
                  <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                  <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                  <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                  <!--  Messages maps -->
      
                  <!-- Splash screen -->
                  <!--
                  <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
                  -->
                  <!-- Splash screen -->
              </activity>
          </application>
          <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
          <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
      
          <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
               Remove the comment if you do not require these default permissions. -->
      
          <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
               Remove the comment if you do not require these default features. -->
          <!-- %%INSERT_FEATURES -->
      
      <!-- %%INSERT_PERMISSIONS -->
      </manifest>
      

      【讨论】:

      • @ssc 我不介意但还是删除了它,不过它会在您的评论中继续存在; )顺便说一句:作为一种中间方式,您可以使用 QtCreator 创建一个新工具包,例如android_armv7_hockey,修改QtActivity.java有吗?或者从 C++ 调用 java 方法,尽管这可能会导致另一个兔子洞。
      • 感谢您的回复! ? 您的 AndroidManifest.xml 文件似乎与我项目中的文件相对应,但版本较旧。
      猜你喜欢
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多