Я пытаюсь интегрировать HockeyApp Android SDK в его последняя версия 4.1.2 в наше приложение Qt для Android. Я мало знаю о разработке для Android или Java в целом, равно как и о внутренностях Qt или HockeyApp.
Существует некоторая общая официальная документация о включении сторонних библиотек Android (например, Java) в проект Qt; однако в настройках развертывания упоминается кнопка Создать AndroidManifest.xml, которой нет в текущей версии Qt Creator 4.2.0, поэтому я не уверен, насколько устарела эта документация или какие части, возможно, еще применить.
документация HockeyApp охватывает только стандартную разработку Android с использованием Android Studio и их поддержка не поддерживает а>.
Кстати, интеграция HockeyApp iOS SDK заняла всего пару часов и в основном заключалась в написании кода моста на Objective C.
Шаг 1. Добавьте SDK в проект
Первый подход
Я попытался следовать приведенной выше документации и добавил разархивированную папку HockeySDK-Android-4.1.2
и файл project.properties
с содержимым.
android.library.reference.1=HockeySDK-Android-4.1.2/libs/
в папку проекта; Я также установил ANDROID_PACKAGE_SOURCE_DIR в <my project>.pro
в эту папку проекта.
Проблема: на этапе сборки 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
Запуск androiddeployqt
с переключателем --verbose
добавляет значительно больше выходных данных, но ноль полезной информации.
Второй подход
Загруженный ZIP-архив HockeyApp Android SDK содержит, помимо некоторой документации, файл libs/HockeySDK-4.1.2.aar
; из этот ответ и этот комментарий, я собираю формат AAR — это просто 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 завершен.
Шаг 2. Используйте SDK в проекте
Возвращаясь к соответствующей документации HockeyApp, я понимаю, что мне нужно изменить код, похожий на
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
файле - Я не буду комментировать практику жесткого кодирования пути
src/android/java
(и многих других путей) в исходникахandroiddeployqt
не один раз, а многократно раз — вместоconst QString
, который хотя бы подготавливает соответствующую (т.е. внешнюю) конфигурацию инструмента - Я не буду комментировать, насколько умно было бы нарушить 50-летнюю передовую практику один инструмент, одна цель — и дублировать большое количество функций, предоставляемых инструментами Qt, Android или Java, такими как создание , подписание, развертывание, установка пакетов и т. д.
- Однако тот факт, что этот инструмент прошел проверку кода и стал одним из основных выпусков Qt, не что иное, как пугающий — и, вероятно, хороший показатель того, что пришло время рассмотреть вопрос об отказе от Qt как технологии в целом.
Пока я пишу это, установка Qt 5.8.0 продолжает зависать, максимально загружая одно ядро ЦП, и это происходит в течение последних ~ 12 часов. Я считаю так.
Мои вопросы
Кто-нибудь добился успеха с Qt, Android и HockeyApp?Есть ли у кого-нибудь намеки/указатели/дикие догадки относительно того, что здесь не так?- никаких дополнительных вопросов; я видел достаточно
Шаг 3. Вызовите Java-код SDK из C++.
(отменено из-за кирпичной стены на шаге 2)