LINUX.ORG.RU

Объясните про Android NDK для дебилоидов.


2

2

Утерждения, которые я считаю истинными, но не уверен в их истинности. Просьба знатокам пофиксить. Вопросы.

1) C++ код для NDK будет скомпилирован в машинные инструкции конкретного камня.

2) Если C++ компилируется в JVM-код, то нафига бы тогда был нужен C++?

3) Мобильных процессоров много, значит приложение должно содержать 50 вариантов машинного кода для одного и того же C++ кода для 50 разных камней, на которых твоё приложение потенциально могут запустить.

3.1) Среда разработки NDK содержит 50 компиляторов под 50 камней и рожает 50 сборок твоего кода под все камни, на которые нацелена твоя разработка.

4) Обычно C++ применяют для реализации каких-то .so-шек, реализующих тяжёлые вычисления, а само приложение проще написать на Java. Оттуда C++-код подключается как java-модули и используется путём создания экземпляров классов определённого типа, только эти классы написаны на C++ и лежат в .so-шках.

5) Целиком приложения на C++ писать смысла мало и никто не пишет void main(...) под NDK.

★☆

Последнее исправление: kiverattes (всего исправлений: 1)

Целиком приложения на C++ писать смысла мало и никто не пишет void main(...) под NDK.

Qt новый позволяет компилировать полностью С++ код под телефон.

abs ★★★
()

C++ код для NDK будет скомпилирован в машинные инструкции конкретного камня.

Да.

Если C++ компилируется в JVM-код, то нафига бы тогда был нужен C++?

Нет. JVM в андроиде нет в принципе, java компилится в далвик (теперь арт), С++ компилится в нативщину.

Мобильных процессоров много, значит приложение должно содержать 50 вариантов машинного кода для одного и того же C++ кода для 50 разных камней, на которых твоё приложение потенциально могут запустить.

Не 50, а меньше, от силы 5, включая х86.

Обычно C++ применяют для реализации каких-то .so-шек, реализующих тяжёлые вычисления, а само приложение проще написать на Java. Оттуда C++-код подключается как java-модули и используется путём создания экземпляров классов определённого типа, только эти классы написаны на C++ и лежат в .so-шках.

Да.

Целиком приложения на C++ писать смысла мало и никто не пишет void main(...) под NDK.

Это возможно только для узкого класса приложений (читай — игрушек). Для доступа к подавляющему большинству API нужна java.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

JVM в андроиде нет в принципе,

Разве Дальвик не является Виртуальной Машиной Ява? )

Не 50, а меньше, от силы 5, включая х86.

Значит релизный «пакет» (или как его?) моего софта будет содержать 5 экземпляров одного функционала под разные каменья?

По поводу «от силы 5» вопрос: например samsung galaxy note, note 2, note 3, S3, S4, S5 — у них только частота и кол-во ядер растёт? Никаких там дополнительных инструкций суперскалярных не добавляется?

Для доступа к подавляющему большинству API нужна java.

То есть, если я хочу запускать встроенное приложение «фотокамера», чтобы получить фотку, то мне надо изначально планировать, что приложение будет написано на java?

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Никаких там дополнительных инструкций суперскалярных не добавляется?

armv6 (можно уже забить), armv7-vfpv3, armv7-vfpv4, armv7-neon, armv8, mips, x86+sse4.2

Больше в голову ничего не приходит.

devl547 ★★★★★
()
$ ls -1d /opt/android-ndk/toolchains/*4.7
/opt/android-ndk/toolchains/arm-linux-androideabi-4.7
/opt/android-ndk/toolchains/mipsel-linux-android-4.7
/opt/android-ndk/toolchains/x86-4.7

других платформ с андроидом нет

sergej ★★★★★
()
Ответ на: комментарий от kiverattes

Значит релизный «пакет» (или как его?) моего софта будет содержать 5 экземпляров одного функционала под разные каменья?

На гуглплей можно залить несколько apk для разных архитектур. Да и нативный код обычно незаметен на фоне байткода и ресурсов приложения. 5 мб приложение превратится в 6 мб, а не в 25.

По поводу «от силы 5» вопрос: например samsung galaxy note, note 2, note 3, S3, S4, S5 — у них только частота и кол-во ядер растёт?

В основном да.

Разве Дальвик не является Виртуальной Машиной Ява? )

Является. Но обычно под jvm понимают не любую жабамашину, а конкретную, от санок/оракли.

То есть, если я хочу запускать встроенное приложение «фотокамера», чтобы получить фотку, то мне надо изначально планировать, что приложение будет написано на java?

Код на java в таком приложении скорее всего будет, а писать проще на одном языке, чем на нескольких. NDK имеет смысл использовать либо при портировании больших кусков готового кода, либо если от C/С++ есть какой-либо реальный профит.

PolarFox ★★★★★
()

1) C++ код для NDK будет скомпилирован в машинные инструкции конкретного камня.

Будет собран под ту архитектуру, которую вы укажете в файле Application.mk в переменной APP_ABI.

2) Если C++ компилируется в JVM-код, то нафига бы тогда был нужен C++?

С чего бы?

3) Мобильных процессоров много, значит приложение должно содержать 50 вариантов машинного кода для одного и того же C++ кода для 50 разных камней, на которых твоё приложение потенциально могут запустить.

Сейчас всего несколько архитектур в последнем NDK - arm, arm-v7, x86 + они же, но для 64 бит.

4) Обычно C++ применяют для реализации каких-то .so-шек, реализующих тяжёлые вычисления, а само приложение проще написать на Java. Оттуда C++-код подключается как java-модули и используется путём создания экземпляров классов определённого типа, только эти классы написаны на C++ и лежат в .so-шках.

Для инициализачии и взаимодействия со стронними либами без java не обойтись. Но тот же гугель недавно выкатил нативную либу для google play services (а там много полезного).
Если сторонние либы не нужны, то можно заюзать native-activity и вообще забить болт на яву.

5) Целиком приложения на C++ писать смысла мало и никто не пишет void main(...) под NDK.

У андроеда своя точка входа, которая позволяет загрузить вашу нативную либу и передать ей управление.

andreyu ★★★★★
()

1) C++ код для NDK будет скомпилирован в машинные инструкции конкретного камня.

не совсем. в инструкции конкретных ABI, которые ты сам выбираешь в Application.mk. например:

APP_ABI := armeabi armeabi-v7a mips x86

весь код при таком конфиге скомпилируется под 4 разных набора инструкций.

2) Если C++ компилируется в JVM-код, то нафига бы тогда был нужен C++?

он компилируется в нативный код, а не в JVM. а еще dalvik/arts != JVM.

3) Мобильных процессоров много, значит приложение должно содержать 50 вариантов машинного кода для одного и того же C++ кода для 50 разных камней, на которых твоё приложение потенциально могут запустить.

см [1]

3.1) Среда разработки NDK содержит 50 компиляторов под 50 камней и рожает 50 сборок твоего кода под все камни, на которые нацелена твоя разработка.

она содержит тулчейны для кросскомпиляции под поддерживаемые ABI, о которых см. [1]. (их больше чем 4, но не 50)

4) Обычно C++ применяют для реализации каких-то .so-шек, реализующих тяжёлые вычисления

обычно - это где? ndk используют чтобы выполнять нативщину на ведроиде. любую.

а само приложение проще написать на Java.

кому как. мне не проще. я как раз щас пишу проект под андроид целиком в нативе, включая гуй (ессно, дергаю Canvas/... через JNI).

Оттуда C++-код подключается как java-модули и используется путём создания экземпляров классов определённого типа, только эти классы написаны на C++ и лежат в .so-шках.

да.

5) Целиком приложения на C++ писать смысла мало и никто не пишет void main(...) под NDK.

можно и так сделать при желании. например, если использовать SDL - можно игру целиком на сях кодить, и не трогать жабу.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от PolarFox

Для доступа к подавляющему большинству API нужна java.

java-APIs можно дергать через jni.

это не руководство к действию. просто таким образом работают всякие там qt, sdl, и т.п.

waker ★★★★★
()
Ответ на: комментарий от PolarFox

На гуглплей можно залить несколько apk для разных архитектур. Да и нативный код обычно незаметен на фоне байткода и ресурсов приложения. 5 мб приложение превратится в 6 мб, а не в 25.

начинаю сомневаться в твоей адекватности. зачем делать несколько APK, когда все в одном вполне уживается?

а насчет незаметности по размеру.. зависит от количества кода. у меня его много, больше чем жабы раз в 200. на жабе только гуй. а в новой версии и гуй будет нативщина.

waker ★★★★★
()
Ответ на: комментарий от kiverattes

То есть, если я хочу запускать встроенное приложение «фотокамера», чтобы получить фотку, то мне надо изначально планировать, что приложение будет написано на java?

скажем так.. это проще написать на java. но можно и на сишечке, если время девать некуда.

waker ★★★★★
()
Ответ на: комментарий от waker

начинаю сомневаться в твоей адекватности. зачем делать несколько APK, когда все в одном вполне уживается?

Несколько апк обычно делают по поводу разного формата текстур, но если нативный код действительно занимает много места, можно разделить по нему.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

начинаю сомневаться в твоей адекватности.

сорри, не сразу дошло что ты сам отвечал на какую-то неадекватность.

waker ★★★★★
()
Ответ на: комментарий от waker

Правильно ли я понимаю, что JNI — это интерфейс не чтобы из явы дёрнуть что-то в C++, а наоборот, чтобы из C++ дёрнуть какую-то java-функцию?

kiverattes ★☆
() автор топика
Ответ на: комментарий от devl547

Тот же Qt идет с компиляторами для андроида под ARMv5, ARMv7, x86, видимо это самые распространенные.

RiseOfDeath ★★★★
()
Ответ на: комментарий от andreyu

Но тот же гугель недавно выкатил нативную либу для google play services

А можно подробностей? А то мне такого на глаза не попадалось.

RiseOfDeath ★★★★
()
Ответ на: комментарий от Pavval

Qt, хотя вроде бы Battle for Wesnoth использует что-то другое.

RiseOfDeath ★★★★
()
Ответ на: комментарий от Pavval

А это как? Точнее, чем?

ручками. создается Activity, в нем custom view, делается native wrapper для canvas api, events, ..., и вперед.

тут главное преимущество в том, что этот же wrapper API реализован на xlib+cairo, поэтому код и под линухом собирать и запускать можно, и тестировать мобильную программу без эмулятора, NDK, и всех этих заманух.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от devl547

Дальвик из джавовского в свой байткод перегоняет(javac->dx->...). Но это тоже байткод и исполняется он с помощью VM.

yacuken ★★★★
()

1. yep

2. в чем вопрос? с++ комплилируется в native код, который потом работает через http://ru.wikipedia.org/wiki/Java_Native_Interface

3. нет. есть только 2 типа армов (теперь три, еще и x64), один интел и один мипс. NDK собирает по одной библиотеке для каждой архитектуры, указанной в .mk файле. Твой .apk будет запускаться только на тех, для которых ты запросил сборку, на других на этапе выполнения получишь library not found

4. нет. между c++ и java нельзя пробросить классы, можно пробросить вызовы c-шных функций, дальше надо городить свой велосипед для получения идентичных классов в j и c++.

5. все верно, т.к. гемороя потом не оберешся, но на пути становления android-developer из c++-ninja в самом начале есть этап «полного отказа от Java». С возрастом проходит.

g0t0
()
Ответ на: комментарий от kiverattes

это интерфейс для дерганья с из джавы и джавы из с.

g0t0
()
Ответ на: комментарий от g0t0

Твой .apk будет запускаться только на тех, для которых ты запросил сборку, на других на этапе выполнения получишь library not found

armv6+armv7 либы запускаются и на x86 девайсах, там эмулятор встроен.

про mips вот не уверен.

между c++ и java нельзя пробросить классы

смотря что под этим подразумевать. для c++->java есть SWIG. для наоборот, возможно, тоже есть SWIG (не проверял), но вообще использовать java-классы из C/C++ можно через JNI.

в самом начале есть этап «полного отказа от Java». С возрастом проходит.

у меня наоборот получилось. выпустил проект на java, огреб с ним геморроя, теперь переделываю на «полный отказ» от java.

на самом деле, конечно, будут компоненты на java в любом случае. но больше никакого java+xml gui.

waker ★★★★★
()
Ответ на: комментарий от waker

Про SWIG не в курсе, но называть JNI С++ интерфейсом крайне вредно. Это C интерфейс, а дальше начинается собственный велосипед для одновременной работы с классами в java и c++.

g0t0
()
Ответ на: комментарий от g0t0

где я его так называл? я вообще только на C пишу, без ++.

waker ★★★★★
()
Ответ на: комментарий от waker

Вопрос. Вот например архитектура x86: со временем там появляются всякие дополнительные суперскалярные и прочие инструкции. Типа там SSE3 и т.п. То есть, я бы x86 делил на разные этапы: 386, 686 и потом ещё 2-3 этапа добавления всяких модных инструкций.

Вопрос вот в чём: бывают два ARM7 с различным набором инструкций — у одного их меньше, а у второго новый комплект каких-нибудь суперскалярных, а у третьего ещё что-нибудь связанное с мультиядерностью? А то я соберу приложение, грубо говоря, «с использованием SSE, SSE2» (это аналогия), а оно не взлетит на старых ARM7...

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

ну прямая аналогия — это, например, armv6 vs armv7a+neon, причем на некоторых девайсах с armv7a нет neon (тегры какие-то)

подключаешь оба ABI в Application.mk:

APP_ABI := armeabi armeabi-v7a

потом делаешь что-то вроде такого в Android.mk

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
	LOCAL_CFLAGS += -DUSE_NEON -DUSE_ASM
	LOCAL_SRC_FILES += myasmcode.S
endif

т.е. дефайнами говоришь, что надо использовать neon и ассемблерные оптимизации, и подключаешь ассемблерный исходник.

дальше, в коде делаешь как-то так:

#include <cpu-features.h>
....
int neon_supported = 0;
int armv7a_supported = 0;
int vfp_supported = 0;
....

    uint64_t features = android_getCpuFeatures ();
    if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) {
        if (features & ANDROID_CPU_ARM_FEATURE_NEON) {
            neon_supported = 1;
        }
        if (features & ANDROID_CPU_ARM_FEATURE_ARMv7) {
            armv7a_supported = 1;
        }
        if (features & ANDROID_CPU_ARM_FEATURE_VFPv3) {
            vfp_supported = 1;
        }
    }

....

#if defined(USE_NEON) && defined(USE_ASM)
if (neon_supported) call_asm_functions ();
else call_c_functions ();
#endif

я так делаю. под x86 у меня специальных оптимизаций на андроиде пока нет, только под ARM.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 2)
Ответ на: комментарий от kiverattes

да, если ты через -mtune/-mcpu/-march включишь компиляцию под конкретный набор инструкций, то конечно бинарь тупо будет вылетать на неизвестных инструкциях. (т.е. аналогично любой другой операционке)

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от vvviperrr

а жабной версии было много разных activities. в нативной версии пока одна, но если надо будет - сделаю несколько, по необходимости.

по сути, вся эта хрень с multiple activities просто навязана архитектурой андроидного гуи-тулкита — есть куча всяких ограничений, и если сделать все в 1 activity — то будет очень неудобно (или просто будет невозможно реализовать задуманное). но в собственном тулките таких ограничений нет, можно разные views/activities как угодно организовывать, а то что java-activity единственный - в принципе пофигу.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

но если надо будет - сделаю несколько, по необходимости

а потом захочешь использовать фрагменты, табы и тп, и погрязнешь в нативном коде, когда в жабке все это за 5 минут накидывается.

vvviperrr ★★★★★
()
Ответ на: комментарий от vvviperrr

не, фрагменты, табы и т.п. — это у меня тоже все будет нативное.

за 5 минут оно в жабке не накидывается, потому что у меня весь бакенд нативный (я упоминал выше), т.е. чтобы забиндить данные в какой-нибудь там listview — приходилось делать кучу jni-биндингов, решать проблемы с многопоточностью, и т.п.

+ у меня таргет 2.x, в котором еще для этих всех фич приходилось тащить compat-либы. а это проблемы с размером, и не только.

разный внешний вид на разных андроидах - тоже беда.

в некоторых прошивках что-то отламывается, т.к. разрабы прошивок что-то криво подкрутили, и т.п.

иными словами, уход от жабогуя позволит избежать тонну проблем фрагментированности андроида. у меня в баглисте висит несколько десятков багов от разных юзеров, которые происходят только на определенных прошивках, и исправить это нет никакой возможности. даже выяснить что происходит не получается. так что это важно.

+ юзеры очень просят возможность делать собственные скины. с жабогуем это, мягко говоря, близко к невозможному.

waker ★★★★★
()
Ответ на: комментарий от Solace

Но лучше этого избегать. Такая жесть.

ты эта.. если есть какой-то конкретный опыт на этот счет - делись. потому что УМВР, и API вполне пристойный. получше, чем в некоторых других языках.

конечно, весь код писать с кучей вызовов жабы через JNI это бред, но написать враппер с нормальным API — не составляет никаких проблем вообще.

итоговый код программы получается ничем не хуже программы на SDL, например. и да, он кроссплатформенный, и запускается на линуксе для быстрой разработки без привлечения эклипсы, эмуляторов, запуска на девайсе, кривых андроидных дебаггеров, и т.п.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от vvviperrr

а потом захочешь использовать фрагменты, табы и тп, и погрязнешь в нативном коде, когда в жабке все это за 5 минут накидывается.

щас вот перечитал эту мессагу.. ты видимо неправильно понял, что именно я делаю. я не дергаю андроидный жабогуй через JNI. у меня полностью свой гуй через canvas. т.е. никаких андроидных фрагментов/табов мне не надо - все свое будет.

waker ★★★★★
()
Ответ на: комментарий от waker

Есть, причем сугубо неудачный. Пришлось портировать игру с iOS на android, с кучей jni-вызовов во всяких дырках и отвратительным знанием самой платформы.

Solace ★★
()
Ответ на: комментарий от Solace

у меня щас ситуация другая. уже есть опыт разработки под ведроид, порт довольно большого линуксового проекта. жабогуй для гуя, ну и вообще куча жабы для биндинга всего и вся из нативщины. получилось адское месиво, которое развивать очень трудно. главные боттлнеки

* отсутствие работающего нативного дебаггера

* корявище жабо-xml-гуй на котором добавить простейшую фичу может занять пару недель времени (для сравнения, в нативщине я могу весь гуй с нуля на том же SDL за это время сделать, настолько он примитивный)

* непредсказуемое поведение все того же жабогуя (и не только) на разных прошивках, в которых реализация пропатчена разработчиками

вобщем, набил шишек, получил бесценный опыт, и решил начать «с чистого листа», и в этот раз сделать все более эффективно.

оставить жабу только там, где ее использование оправдано, остальное делать в нативе. причем из предыдущей версии вполне очевидно, что лучше оставить на жабе, а что переписать в нативе для ускорения разработки, и улучшения результата.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

Дебагер - это вообще жестокая вещь. Пришлось выкручиваться логами.
С гуем была интересная вещь. Если слышал - cocos2dx. Использовался он. Но пришлось плодить кучу костылей, включая правку самих сорцов, ибо все запускалось на одной activity.
Помимо этого могу вспомнить лишь ужасную связку из qtcreator+bash для автоматизации всего процесса и отсутствие нормального эмулятора.

Solace ★★
()
Последнее исправление: Solace (всего исправлений: 1)
Ответ на: комментарий от waker

для сравнения, в нативщине я могу весь гуй с нуля на том же SDL за это время сделать, настолько он примитивный

это только так кажется. писали мы как-то свой гуи тулкит как раз на sdl. у qt тогда lgpl не было, контора зажопила косарь баксов. писали примерно полгода, сделали основные виджеты. последующие ~2 года вылавливали баги. надо бы его под андроид портануть попробовать...

я не спорю, если сам рисуешь гуй можно делать что угодно. но быстрее и проще пользоваться уже готовыми либами и иногда пойти на компромис, если фреймворк не предоставляет простого способа реализовать задуманное.

vvviperrr ★★★★★
()
Последнее исправление: vvviperrr (всего исправлений: 1)
Ответ на: комментарий от vvviperrr

увы, подходящих готовых вещей нет. но есть много опыта по разработке разнообразных gui с нуля, в т.ч. для игр. так что я, в принципе, могу адекватно оценить время требуемое для разработки.

waker ★★★★★
()
Ответ на: комментарий от vvviperrr

Смотря для чего тебе гуй нужен. Как бы для разных целей довольно большие различия в подходе.

Solace ★★
()
Ответ на: комментарий от vvviperrr

единственная большая проблема, о которой я знаю - это accessibility. т.е. поверх своего тулкита придется накручивать андроидный accessibility tree, чтобы подружить с talkback, делать навигацию по гую через directional controls, и т.п.

это как раз положительная фича жабогуя, т.к. получается почти нахаляву.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

Попробую пересказать что я понял. В жабе принято создавать много activity - по одной на каждое возможное окно твоего приложения, грубо говоря.

Вы создаёте в жабе одну activity, а потом уже из C++ рассматриваете как что-то типа пиксельного буфера, где вы можете сами рисовать что угодно из нативного кода.

Что такое «проблемы фрагментированности андройда»? Это когда на разных версиях андроида кнопка выглядит по-разному? То есть, вы рисуете эту кнопку из нативного кода сами пикселями и линиями (либо картинки показываете) и забиваете болт на эти проблемы?

А что такое canvas? Это некий элементарный буфер размером с весь экран, на котором вы можете максимально быстро выводить любые пиксели?

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)
Ответ на: комментарий от kiverattes

В жабе принято создавать много activity - по одной на каждое возможное окно твоего приложения, грубо говоря.

зависит от приложения. т.е. вовсе необязательно. но обычно одной activity невозможно обойтись. не потому что так принято, а просто потому что так задуман андроидный тулкит.

Вы создаёте в жабе одну activity, а потом уже из C++ рассматриваете как что-то типа пиксельного буфера, где вы можете сами рисовать что угодно из нативного кода.

угу. только не пиксельный буфер, а canvas (в linux версии cairo_t), но это не принципиально. можно с тем же успехом использовать пиксельный буфер, или opengl context.

Что такое «проблемы фрагментированности андройда»?

это когда на разных девайсах/прошивках/версиях один и тот же код приводит к разному результату.

То есть, вы рисуете эту кнопку из нативного кода сами пикселями и линиями (либо картинки показываете) и забиваете болт на эти проблемы?

именно.

А что такое canvas?

http://developer.android.com/reference/android/graphics/Canvas.html

Это некий элементарный буфер размером с весь экран

не совсем во весь экран. у меня используется linear layout вертикальной ориентации, в него воткнуто несколько виджетов - admob, drawingview. drawingview это мой custom view, который рисуется через canvas из нативного кода, admob понятно, и еще планирую как-то втыкать туда андроидный text input, чтобы ввод текста свой не корячить.

waker ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.