Разработка приложений для Android на С++. Юрий Береза, Shturmann

51
Разработка приложений для Android на C++ Берёза Юрий программист Shturmann YaC, Москва, 19 сентября 2011 года 1

description

Юрий Береза, ShturmannОкончил факультет приборостроения Московской государственной академии приборостроения и информатики. В 2004 году пришел на работу в отдел мобильных разработок компании «Макцентр». Занимался разработкой под огромное число мобильных платформ: Windows Mobile, Symbian, Android, Embedded linux и iOS. В данный момент работает руководителем группы в компании «Контент Мастер», где занимается разработкой автомобильной навигации Shturmann.Тема докладаРазработка приложений для Android на С++.ТезисыПлатформа Android становится популярнее с каждым годом. Несмотря на то, что основным языком разработки приложений для Android является Java, часто для написания кросс-платформенных приложений или при использовании сторонних библиотек программистам приходится использовать С или С++. К сожалению, разработка на С++ для платформы Android описана довольно скупо, и зачастую приходится тратить много времени на поиск нужной информации. В докладе будут представлены ответы на основные вопросы по всему циклу разработки: как писать С++ код, который будет работать на Android, как его отлаживать и находить ошибки во время падения приложений, есть ли возможность профилировать код и где искать дополнительную информацию по этим вопросам.

Transcript of Разработка приложений для Android на С++. Юрий Береза, Shturmann

Page 1: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разработка приложений для Android на C++

Берёза ЮрийпрограммистShturmann

YaC, Москва, 19 сентября 2011 года1

Page 2: Разработка приложений для Android на С++. Юрий Береза, Shturmann

С чего начать

• Linux

• Java

• Eclipse

• C++

• GCC

• GDB

• Android SDK

2

Page 3: Разработка приложений для Android на С++. Юрий Береза, Shturmann

3

Page 4: Разработка приложений для Android на С++. Юрий Береза, Shturmann

4

Page 5: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Что такое NDK?http://developer.android.com/sdk/ndk/index.html

• Заголовочные файлы и библиотеки

•GCC компилятор

• Система сборки приложений

•Набор дополнительных утилит

5

Page 6: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Создание проекта

•Запустить Eclipse•Указать в настройках путь к SDK•Запустить мастер создания Android приложения

6

Page 7: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Sequoyah Android Native Code Supporthttp://www.eclipse.org/sequoyah/

7

Page 8: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Добавляем поддержку NDK

8

Page 9: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Application.mk

APP_MODULES := YaCAPP_CFLAGS := -DDEBUG -D__ANDROID__APP_OPTIM := debugAPP_STL := gnustl_staticAPP_ABI := armeabi armeabi-v7a

9

Page 10: Разработка приложений для Android на С++. Юрий Береза, Shturmann

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := YaCLOCAL_CFLAGS := -I$(LOCAL_PATH)/incLOCAL_SRC_FILES := YaC.cppLOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

Android.mk

10

Page 11: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Поддержка расширенных инструкций NEON

http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html

Anroid.mk

ifeq ($TARGET_ARCH_ABI), armeabi-v7a)! LOCAL_ARM_NEON := true! LOCAL_ARM_MODE := armendif

11

Page 12: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Или

#include <cpu-features.h>

void do_something(){ if ((android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_FETURE_NEON)) { do_something_with_neon(); }}

12

Page 13: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI. Java

package com.shturmann.yac;

public class YaCActivity { private native void doSomething(); static { System.loadLibrary("YaC"); }}

13

Page 14: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI. Java

package com.shturmann.yac;

public class YaCActivity { private native void doSomething(); static { System.loadLibrary("YaC"); }}

14

Page 15: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI. Java

package com.shturmann.yac;

public class YaCActivity { private native void doSomething(); static { System.loadLibrary("YaC"); }}

15

Page 16: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI. Java

package com.shturmann.yac;

public class YaCActivity { private native void doSomething(); static { System.loadLibrary("YaC"); }}

16

Page 17: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI

Java C/usr/bin/javah+ =

17

Page 18: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI.C++

JNIEXPORT void JNICALL Java_com_shturmann_yac_YaCActivity_doSomething(JNIEnv * env, jobject obj){ ...}

18

Page 19: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI.C++

JNIEXPORT void JNICALL Java_com_shturmann_yac_YaCActivity_doSomething(JNIEnv * env, jobject obj){ ...}

19

Page 20: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNIEnvJavaVM * gJVM = 0;

JNIEXPORT void JNICALLJava_com_shturmann_yac_YaCActivity_init(JNIEnv * env, jobject obj){

gJVM = (*env)->GetJavaVM(env, &gJVM);}

void someInternalFunction(){ JNIEnv * env = 0; (*gJVM)->AttachCurrentThread(gJVM, &env, 0);} 20

Page 21: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Локальные/глобальные ссылки

jclass * gYac = 0;

JNIEXPORT void JNICALLJava_com_shturmann_yac_YaCActivity_doSomething(JNIEnv * env, jobject obj){ jclass yac = (*env)->GetObjectClass(env, obj); gYac = (*env)->NewGlobalRef(env, yac);}

21

Page 22: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNIEnv::FindClass

jclass gYac = 0;

JNIEXPORT void JNICALL Java_com_shturmann_yac_YaCActivity_init(JNIEnv * env, jobject obj){ jclass yac = (*env)->FindClass(env,

«com/shturmann/yac/YaCActivity»); gYac = (*env)->NewGlobalRef(env, yac);}

22

Page 23: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNIEnv::ExceptionCheck

JNIEXPORT void JNICALL Java_com_shturmann_yac_YaCActivity_init(JNIEnv * env, jobject obj){ ... if ( !(*env)->ExceptionCheck(env) ) { ... }}

23

Page 24: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNIEnv::PushLocalFrame/PopLocalFrame

JNIEXPORT void JNICALL Java_com_shturmann_yac_YaCActivity_init(JNIEnv * env, jobject obj){ (*env)->PushLocalFrame(env, 100500); ... (*env)->PopLocalFrame(env, NULL);}

24

Page 25: Разработка приложений для Android на С++. Юрий Береза, Shturmann

JNI

http://java.sun.com/docs/books/jni/download/jni.pdf

25

Page 26: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Дополнительные библиотеки

• OpenGL ES 1.1 / OpenGL ES 2.0

• OpenSL

• C++ и wchar_t

• http://www.crystax.net/ru/android/ndk

• Boost

• https://github.com/MysticTreeGames/Boost-for-Android

• CURL

26

Page 27: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Запускаем сборку приложения

• ndk-build

• ant install

27

Page 28: Разработка приложений для Android на С++. Юрий Береза, Shturmann

28

Page 29: Разработка приложений для Android на С++. Юрий Береза, Shturmann

ОтладкаAndroid 2.3 Gingerbred

• ndk-gdb • Eclipse

http://mitya.pp.ru/gdb/gdb_toc.html29

Page 30: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками ********** Crash dump: **********Build fingerprint: 'google/soju/crespo:2.3.4/GRJ22/121341:user/release-keys'pid: 7348, tid: 7348 >>> com.shturmann.yac <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),fault addr 00000000Stack frame #00 pc 00000716 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #01 pc 00000740 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #02 pc 00017e34 /system/lib/libdvm.soStack frame #03 pc 0004968c /system/lib/libdvm.soStack frame #04 pc 0004ee62 /system/lib/libdvm.so

30

Page 31: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками ********** Crash dump: **********Build fingerprint: 'google/soju/crespo:2.3.4/GRJ22/121341:user/release-keys'pid: 7348, tid: 7348 >>> com.shturmann.yac <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),fault addr 00000000Stack frame #00 pc 00000716 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #01 pc 00000740 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #02 pc 00017e34 /system/lib/libdvm.soStack frame #03 pc 0004968c /system/lib/libdvm.soStack frame #04 pc 0004ee62 /system/lib/libdvm.so

31

Page 32: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками ********** Crash dump: **********Build fingerprint: 'google/soju/crespo:2.3.4/GRJ22/121341:user/release-keys'pid: 7348, tid: 7348 >>> com.shturmann.yac <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),fault addr 00000000Stack frame #00 pc 00000716 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #01 pc 00000740 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #02 pc 00017e34 /system/lib/libdvm.soStack frame #03 pc 0004968c /system/lib/libdvm.soStack frame #04 pc 0004ee62 /system/lib/libdvm.so

32

Page 33: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками ********** Crash dump: **********Build fingerprint: 'google/soju/crespo:2.3.4/GRJ22/121341:user/release-keys'pid: 7348, tid: 7348 >>> com.shturmann.yac <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),fault addr 00000000Stack frame #00 pc 00000716 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #01 pc 00000740 /data/data/com.shturmann.yac/lib/libYaC.soStack frame #02 pc 00017e34 /system/lib/libdvm.soStack frame #03 pc 0004968c /system/lib/libdvm.soStack frame #04 pc 0004ee62 /system/lib/libdvm.so

33

Page 34: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками

• addr2line

• objdump

• ndk-stack

34

Page 35: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками

$ adb logcat -d | ndk-stack -sym ~/src/obj/local/armeabi

35

Page 36: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками

Stack frame #00 pc 00000716/data/data/com.shturmann.yac/lib/libYaC.so:Routine get_a in /home/ybereza/src/YaC/yac/jni/YaC.cpp:13

Stack frame #01 pc 00000740/data/data/com.shturmann.yac/lib/libYaC.so:Routine Java_com_shturmann_yac_YaCActivity_doSomething in /home/ybereza/src/YaC/yac/jni/YaC.cpp:24

36

Page 37: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками

Stack frame #00 pc 00000716/data/data/com.shturmann.yac/lib/libYaC.so:Routine get_a in /home/ybereza/src/YaC/yac/jni/YaC.cpp:13

Stack frame #01 pc 00000740/data/data/com.shturmann.yac/lib/libYaC.so:Routine Java_com_shturmann_yac_YaCActivity_doSomething in /home/ybereza/src/YaC/yac/jni/YaC.cpp:24

37

Page 38: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Разбираемся с ошибками

Stack frame #00 pc 00000716/data/data/com.shturmann.yac/lib/libYaC.so:Routine get_a in /home/ybereza/src/YaC/yac/jni/YaC.cpp:13

Stack frame #01 pc 00000740/data/data/com.shturmann.yac/lib/libYaC.so:Routine Java_com_shturmann_yac_YaCActivity_doSomething in /home/ybereza/src/YaC/yac/jni/YaC.cpp:24

38

Page 39: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельноvoid install_sighandler(){ struct sigaction default_action;

struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction));

sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = linux_sig_handler; sigemptyset(&sa.sa_mask);

sigaction(SIGSEGV, &sa, &default_handler)}

39

Page 40: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельноvoid install_sighandler(){ struct sigaction default_action;

struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction));

sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = linux_sig_handler; sigemptyset(&sa.sa_mask);

sigaction(SIGSEGV, &sa, &default_handler)}

40

Page 41: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельно

void linux_sig_handler(int sig, struct siginfo_t* info, void* context){ LOG_FLUSH; default_handler.sa_handler(sig);}

41

Page 42: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельно

void linux_sig_handler(int sig, struct siginfo_t* info, void* context){ LOG_FLUSH; default_handler.sa_handler(sig);}

42

Page 43: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельно

43

#include <asm/sigcontext.h>

struct ucontext{ unsigned long uc_flags; struct ucontext *uc_link; stack_t uc_stack; sigcontext uc_mcontext;}

Page 44: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельно

#include <asm/sigcontext.h>

struct ucontext{ unsigned long uc_flags; struct ucontext *uc_link; stack_t uc_stack; sigcontext uc_mcontext;}

44

Page 45: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Ловим сигналы самостоятельно

/proc/<id вашего процесса>/maps

45

Page 46: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Где взять

https://bitbucket.org/ybereza/yac/src

46

Page 47: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Профилирование

47

Page 48: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Профилирование

Но! 48

Page 49: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Профилирование

DDMS Native Heap

~/.android/ddms.cfg“native=true”

:$ emulator -help-memcheck:$ emulator -memcheck 1

:$ ddms Из корня вашего проекта

49

Page 50: Разработка приложений для Android на С++. Юрий Береза, Shturmann

Для чего все это нужно?

50