Android and cpp

45
Android and C++ Joan Puig Sanz

Transcript of Android and cpp

Page 1: Android and cpp

Android and C++Joan Puig Sanz

Page 2: Android and cpp

About me

@joanpuigsanz

2

Page 3: Android and cpp

What we will see?

1. Apps for all the platforms 2. C++ 11 3. Libraries 4. Java, C++ and JNI 5. Final thoughts

3

Page 4: Android and cpp

Text

The same app running in all the platforms4

Page 5: Android and cpp

5

Page 6: Android and cpp

Most common solutions?

Xamarin

PhoneGap Adobe Air

Titanium6

Page 7: Android and cpp

7

Page 8: Android and cpp

✦ Not native UI

✦ Slow performance

✦ Custom components.

✦ Depend on a company

✦ Poor user experience

8

Page 9: Android and cpp

Smooth

UI

UX

Good user experience

9

Page 10: Android and cpp

Text

An other old solution…C++

10

Page 11: Android and cpp

Why C++?

Cross platform language

Better performance

Mature language

Lots of libraries

11

Page 12: Android and cpp

Combining C++ with Android

Native UI and UX

JNI

C++ core

12

Page 13: Android and cpp

Text

C++ 11 features

13

Page 14: Android and cpp

C++11 Features :: Auto

The compiler deducing the typeauto i = 42; // i is an intauto l = 42LL; // l is an long longauto p = new Foo(); // p is a foo*  

std::map<std::string, std::vector<int>> map;for(auto it = begin(map); it != end(map); ++it) {}  

14

Page 15: Android and cpp

C++11 Features :: Range-based for loops

Iterate collections with foreachstd::vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);

for (auto value : v) { std::cout << value << std::endl;}

15

Page 16: Android and cpp

C++11 Features :: Smart pointersunique_ptr: Ownership of a memory resource it is not shared, but it can be transferred to another unique_ptr

shared_ptr: Ownership of a memory resource should be shared

weak_ptr: Holds a reference to an object managed by a shared_ptr, but does not contribute to the reference count; it is used to break dependency cycles.

16

Page 17: Android and cpp

C++11 Features :: Lambdas

Powerful feature borrowed from functional programming.

You can use lambdas wherever a function object or a functor or a std::function is expected

std::function<int(int)> lfib = [&lfib](int n) { return n < 2 ? 1 : lfib(n-1) + lfib(n-2);};

17

Page 18: Android and cpp

C++11 Features :: More

Final and overridenon-member begin() and end()Initializer listsObject construction improvementUnrestricted unionsUser-defined literalsstatic_assertStrongly-typed enums…

18

Page 19: Android and cpp

Text

Complementing C++Libraries

19

Page 20: Android and cpp

Complementing C++C++11 standard library is missing utilities:

HTTP Requests

XML and JSON

Big numbers

Security

Math20

Page 21: Android and cpp

C++ libs :: BoostSupports:

Licence:

AS IS

Big community

Lots of modules21

Page 22: Android and cpp

C++ libs :: JuceSupports:

Licence:

Core: AS IS

Other modules: GPL and commercial licence

Very well written code

Easy to use

No WP (for now)

22

Page 23: Android and cpp

C++ libs :: QtSupports:

Licence:

GPL and commercial licence

Big community

Lots of modules23

Page 24: Android and cpp

Text

Putting stuff together JNI

24

Page 25: Android and cpp

Calling JNI from JavaDeclare native methods

Implement C method

private native void doSomethingNative (String str);  

JNIEXPORT void Java_com_example_MyClass_doSomethingNative (JNIEnv *env, jobject obj, jstring s){ const char* const utf8 = env->GetStringUTFChars (s, nullptr); CharPointer_UTF8 utf8CP (utf8); String cppString (utf8CP); env->ReleaseStringUTFChars (s, utf8);

// Do Something}

25

Page 26: Android and cpp

Calling JNI from JavaJNIEXPORT void Java_com_example_MyClass_doSomethingNative

(JNIEnv *env,jobject obj,jstring s)

Required macro to support Windows

Java + package_name + className + methodName

26

Page 27: Android and cpp

Calling C from JavaJNIEXPORT void Java_com_example_MyClass_doSomethingNative(JNIEnv *env,

jobject obj,

jstring s)

Structure to access all the JNI functionsJava object that calls the native function

Java method arguments

27

Page 28: Android and cpp

Local and global referencesLocal reference will be managed by java

A global reference is managed by the developer

Max number

of java

references

= 512

28

Page 29: Android and cpp

Calling Java from C public String myMethod (int[] array, boolean enabled)

29

Page 30: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass (myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass , ”methodName", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

30

Page 31: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass , ”methodName", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

Must not be NULL This is the java object that has the method

31

Page 32: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass, ”myMethod", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

Method signature

32

Page 33: Android and cpp

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass, ”myMethod", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

Calling Java from C public String myMethod (int[] array, boolean enabled)

Method signature

Type Signature Java TypeZ BooleanB byteC charS shortI intJ longF floatD double

L class ; full qualified class[type; type[]

33

Page 34: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass, ”myMethod", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

Method signature

34

Page 35: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass , ”myMethod", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

35

Page 36: Android and cpp

Calling Java from C

JNIEnv* env = getEnv();

jclass myJavaClass = env->GetObjectClass(myJavaObject);jmethodID myJavaMethod = env->GetMethodID(myJavaClass , ”myMethod", "([I;Z)Ljava/lang/String");

jstring jresult = (jstring) env->CallObjectMethod (myJavaObject, myJavaMethod , myIntArray, myBoolean);

// Do something

env->DeleteLocalRef (jresult);env->DeleteLocalRef (myJavaClass);

public String myMethod (int[] array, boolean enabled)

36

Page 37: Android and cpp

Java and C++ object binding

37

Page 38: Android and cpp

Java (OO)

C

C++ (OO)

Java and C++ object binding

38

Page 39: Android and cpp

Java (OO)

C

C++ (OO)

Java and C++ object binding

39

Page 40: Android and cpp

Foo Java implementationpublic class Foo { native void destroyCppInstanceNative(double ref); native long newCppInstanceNative(); native String getStringNative(double ref); private double _ref = 0; public Foo() { _ref = newCppInstanceNative(); } public String getString() { return getStringNative(_ref); } public void destroy() { destroyCppInstanceNative(_ref); }} 40

Page 41: Android and cpp

Foo Java implementationJNIEXPORT long Java_com_example_Foo_newCppInstanceNative(JNIEnv *env, jobject obj) { Foo* newFoo = new Foo(); return (double)(newFoo);}

JNIEXPORT jstring Java_com_example_Foo_getStringNative(JNIEnv *env, jobject obj, double ref) { Foo* foo = (Foo*)(ref); jstring jStringResult = env->NewStringUTF (foo->getString()); return jStringResult;}

JNIEXPORT void Java_com_example_Foo_destroyCppInstanceNative(JNIEnv *env, jobject obj, double ref) { Foo* foo = (Foo*)(ref); delete foo;}   41

Page 42: Android and cpp

Text

Some advice to live happier with C++

42

Page 43: Android and cpp

Some adviceCode quality! (Code conventions, code reviews, etc.)

C++ is not a read only code, don’t put the blame on it

Remember to initialise all the values in the constructor

Use unity builds to speed up compilation time

JNI could be painful. Check out djinni to generate cross-language type declarations and interface bindings.

dropbox/djinni  43

Page 44: Android and cpp

Final thoughtsPros

Same core and with native UI/UX per platform Better performance Faster cross platform development Easier maintenance

Cons Need to learn a new language Android apps will be bigger (code compiled for different architectures)

Can be fixed distributing specific apk per each architecture

44

Page 45: Android and cpp

?@joanpuigsanz

45