- Android Native Development Kit Cookbook
- Feipeng Liu
- 923字
- 2021-07-27 18:07:27
Manipulating classes in JNI
The previous recipe discusses that Android JNI supports three different kinds of references. The references are used to access the reference data types, including string, class, instance object, and array. This recipe focuses on class manipulations in Android JNI.
Getting ready
The Managing References in NDK recipe should be read first before going through this recipe.
How to do it…
The following steps describe how to build a sample Android application that illustrates class manipulation in JNI:
- Create a project named
ClassManipulation
. Set the package name ascookbook.chapter2
. Create an activity namedClassManipulationActivity
. Under the project, create a folder namedjni
. Refer to the Loading native libraries and registering native methods recipe of this chapter if you want more detailed instructions. - Create a file named
classtest.c
under thejni
folder, then implement thefindClassDemo
,findClassDemo2
,GetSuperclassDemo
, andIsAssignableFromDemo
methods. We can refer to the downloadedClassManipulation
project source code. - Modify
ClassManipulationActivity.java
by adding code to load the native library, declare native methods, and invoke native methods. - Create a
Dummy
class and aDummySubClass
subclass that extends theDummy
class. Create aDummyInterface
interface and aDummySubInterface
subinterface, which extends theDummyInterface
. - Modify the
layout
XML file, add theAndroid.mk
build file, and build the native library. Refer to steps 8 to 10 of the the Loading native libraries and registering native methods recipe of this chapter for details. - We're now ready to run the project. We'll present the output while discussing each native method in the following section.
How it works…
This recipe demonstrates the manipulation of classes in JNI. We highlight a few points as follows:
- Class descriptor: A class descriptor refers to the name of a class or an interface. It can be derived by replacing the "
.
" character in Java with "/
" in JNI programming. For example, the descriptor for classjava.lang.String
isjava/lang/String
. - FindClass and class loader: The JNI function
FindClass
has the following prototype:jclass FindClass(JNIEnv *env, const char *name);
It accepts a
JNIEnv
pointer and a class descriptor, and then locates a class loader to load the corresponding class. It returns a local reference to an initialized class, orNULL
in case of failure.FindClass
uses the class loader associated with the topmost method of the call stack. If it cannot find one, it will use the "system" class loader. One typical example is that after we create a thread and attach it to the VM, the topmost method of the call stack will be as follows:dalvik.system.NativeStart.run(Native method)
This method is not part of our application code. Therefore the "system" class loader is used.
Tip
A thread can be created at Java (called the managed thread or Java thread) or native code (called the native thread or non-VM thread). The native thread can be attached to a VM by calling the JNI function
AttachCurrentThread
. Once attached, the native thread works just like a Java thread, running inside a native method. It remains attached until the JNI functionDetachCurrentThread
is called.In our
ClassManipulation
project, we illustratedFindClass
withfindClassDemo
andfindClassDemo2
native methods. ThefindClassDemo
method runs in a VM created thread. TheFindClass
call will locate the class loader properly. ThefindClassDemo2
method creates a non-VM thread and attaches the thread to VM. It illustrates the case we described in the preceding section. The logcat output for calling the two native methods is as follows:As shown in the output, the non-VM thread loads the
String
class successfully but not theDummy
class defined by us. The way to work around this issue is to cache a reference to theDummy
class in theJNI_OnLoad
method. We'll provide a detailed example in the Caching jfieldID, jmethodID, and referencing data to improve performance recipe. GetSuperclass
: The JNI functionGetSuperclass
has the following prototype:jclass GetSuperclass(JNIEnv *env, jclass clazz);
It helps us to find the superclass of a given class. If
clazz
isjava.lang.Object
, this function returnsNULL
; if it's an interface, it returns a local reference tojava.lang.Object
; if it's any other class, it returns a local reference to its superclass.In our
ClassManipulation
project, we illustratedGetSuperclass
with theGetSuperclassDemo
native method. We created aDummy
class and aDummyInterface
interface in Java code, whereDummySubClass
extendsDummy
, andDummySubInterface
extendsDummyInterface
. In the native method, we then invokedGetSuperclass
tojava.lang.Object
,DummySubClass
, andDummySubInterface
respectively. The following is a screenshot of the logcat output:As shown in the screenshot,
GetSuperclass
can find the superclass ofDummySubClass
successfully. In this native method, we used a utility functionnativeGetClassName
, where we called thetoString
method. We'll cover more about how to make such method calls in the Calling instance and static methods in JNI recipe.IsAssignableFrom
: The JNI functionIsAssignableFrom
has the following prototype:jboolean IsAssignableFrom(JNIEnv *env, jclass cls1, jclass cls2);
This function returns
JNI_TRUE
ifcls1
can be safely casted tocls2
, andJNI_FALSE
otherwise. We demonstrated its usage with the native methodIsAssignableFromDemo
. We obtained a local reference toDummySubClass
, and calledGetSuperclass
to get a local reference toDummy
. Then, we calledIsAssignableFrom
to test if we can castDummySubClass
toDummy
and vice versa. The following is a screenshot of the logcat output:As expected, the subclass can be safely cast to its superclass, but not the other way round.
- Java語言程序設計
- Boost程序庫完全開發指南:深入C++”準”標準庫(第5版)
- TypeScript入門與實戰
- Cocos2D-X權威指南(第2版)
- JavaScript+DHTML語法與范例詳解詞典
- Kubernetes實戰
- Learning SQLite for iOS
- Mastering Scientific Computing with R
- R的極客理想:工具篇
- Reactive Programming With Java 9
- 高級語言程序設計(C語言版):基于計算思維能力培養
- Learning SciPy for Numerical and Scientific Computing(Second Edition)
- Nginx Lua開發實戰
- C語言程序設計
- INSTANT Sinatra Starter