4

I always see the term android native code here and there but not sure what exactly it is. So which part of android is android native code? Are Application, Activity, Fragment, View, Looper android native code?

More context: I'm trying to understand the shadow in robolectric tests, and in the doc it is said that "Android native code cannot execute on your development machine", so I'm wondering are classes like Application, Activity etc android native code referred here? http://robolectric.org/extending/

Changda Li
  • 123
  • 1
  • 8

2 Answers2

5

The word native in Android development is overloaded.

Going through link you provided for Robolectric:

There are limitations however:

  1. Native code - Android native code cannot execute on your development machine.
  2. Out of process calls - There are no Android system services running on your development machine.
  3. Inadequate testing APIs - Android includes next to no APIs suitable for testing

Roboletric fills these gaps with a set of classes known as Shadows...

So in this case the Android native code quote either refers to:

  • The Android Framework classes like Activity,Fragment,View where with only the Android SDK apps needs an emulator or device to run. But Roboletric bring its own Android Framework code which can be 'enhanced' by 'Shadows' for testing apps.

OR

Later that same page:

Using byte code instrumentation Robolectric is able to weave in cross platform fake implementations to substitute for native code and add additional APIs to make testing possible.

The substitute for native code refers to Java/Kotlin APIs belonging to the Android Framework which Roboletric is substituting for to provide a test environment. Again, those would be the Activity, Fragment, View, etc. you were referring to.

The usage of the term 'native' in this case is similar a developer using a third-party app building framework like 'React Native', 'Ionic', 'Flutter', 'Xamarian', or 'Cordova/Phonegap', they may use a custom component written in Java/Kotlin as a native component to achieve some function which can only be done by direct interaction with the Android Framework but not in the language/API of that third-party framework like Javascript, Dart, or C#.

Java and its kin (Kotlin, Scala, etc.) refers to calling C/C++ code as native via the Java Native Interface (JNI) and on Android is facilitated by the Native Development Kit (NDK). Third party app development frameworks that sit on top of the mobile framework will refer to calls into the original mobile framework as "native".

Sadly as this is part of the terminology used in mobile development so a careful reading of the use of the word "native" is required.

Personally I would prefer if documentation using the word native included the language like native Java/Kotlin APIs or native C/C++ APIs as the first instance in the linked page had me going back and forth about the author's meaning.

Follow up to questions in comments

  1. You mentioned that "they may use a custom component written in Java/Kotlin as a native component", you are referring to Activity, Fragment etc when saying custom component, right?

In that particular section I was referring to third-party app frameworks calling into classes that are Android Framework or directly call parts of it. Normally those third-party app frameworks already wrap/expose Activity, View, etc. but you as a developer may need a library or other custom Java/Kotlin code which can be invoked by the third-party app framework language (Javascript, Dart, C#). From the perspective of the third party app framework the 'wrapped Java/Kotlin library' is a native component as it is "native" to the mobile environment. That wrapped library code isn't written in Javascript, Dart or C#. Again the meaning of "native" is overloaded.

  1. In the first paragraph of link, the author is emphasizing that we will run "real Android code" in robolectric. But as we analyzed, robolectric is shadowing the basic building block like Activity, Fragment, which seems contradictory to me, so the only explanation I can think of is that the ShadowActivity is wrapping the original implementation of real Activity, do you think that is the case?

Yes, the ShadowActivity is "wrapping" the original implementation of real Activity, I would take note that the author states: Shadow objects are not quite Proxies, not quite Fakes, not quite Mocks or Stubs.

It is important that shadow methods are implemented on the corresponding shadow of the class in which they were originally defined. Otherwise Robolectric’s lookup mechanism will not find them (even if they have been declared on a shadow subclass.)

and

Shadow class inheritance hierarchy does not always mirror that of their associated Android classes, it is sometimes necessary to make calls through these real objects so that the Robolectric runtime will have the opportunity to route them to the correct Shadow class based on the actual class of the object

So regular Java inheritance isn't quite the correct mental model for Shadows.

Morrison Chang
  • 11,691
  • 3
  • 41
  • 77
  • @MartinZeitler Oh I agree on the abuse, but if developers are going to see the terminology in the wild a more correct understanding is better. What part of my answer is egregious/incorrect? – Morrison Chang Sep 30 '19 at 01:23
  • @MartinZeitler Its turtles all the way down, JVM calls into C land "native", third party app frameworks calls into Android runtime "native". I'll add that to the answer, but will take constructive feedback. – Morrison Chang Sep 30 '19 at 01:33
  • While we can have a discussion of what does "native" mean on a platform with Ahead-Of-Time and Runtime Compilation even if the language itself is based on VM. I'm not sure how that answers my question of "what is wrong with my answer". If you feel it is so egregious, please put your own down. – Morrison Chang Sep 30 '19 at 01:40
  • @MartinZeitler Made my corrections, if you approve lets clean up the comments. – Morrison Chang Sep 30 '19 at 02:01
  • Think it is more clear now, however Kotlin is also trans-piled to Java byte-code - while native basically always refers to binary machine code. – Martin Zeitler Oct 01 '19 at 02:38
  • Thanks @MorrisonChang for your detailed answer, really appreciate that! So can I ask for some clarification? 1. You mentioned that "they may use a custom component written in Java/Kotlin as `a native component`", you are referring to `Activity`, `Fragment` etc when saying `custom component`, right? – Changda Li Oct 01 '19 at 03:00
  • 2. In the first paragraph of [link](http://robolectric.org/extending/), the author is emphasizing that we will run "real Android code" in robolectric. But as we analyzed, robolectric is shadowing the basic building block like `Activity`, `Fragment`, which seems contradictory to me, so the only explanation I can think of is that the `ShadowActivity` is wrapping the original implementation of real `Activity`, do you think that is the case? – Changda Li Oct 01 '19 at 03:00
  • @ChangdaLi Updated my answer, probably a bit verbose. Shadows is getting off-topic for the original question. Any further concerns about development of Shadows should get its own question. – Morrison Chang Oct 01 '19 at 04:02
4

Android native code is not Java or Kotlin. It is not some classes like Activity or Fragment. Android native code is C/C++. Here is a bit of info about SDK(NDK). And here you can find general overview of NDK(native development kit).

Hope it helps.

Pavlo Ostasha
  • 14,527
  • 11
  • 35