Well, long time not come, busy become a dog, but a lot of harvest, this article is one of them.
Recently the JNI this thing deep learning, although also done before, but are relatively loose, there is no system to the entire knowledge framework and technical system carding. Online also read a lot of blog, basically said is the environment configuration and then a hello from jni stuff, and then there is no specific application and the corresponding core API introduction, the introduction of its ideas is less, so I want to summarize an article out, not to install force, Is afraid of half a year himself and all back to their own (who believe AH) ...
First come to Zhang Gregory Uncle's figure Town building!
What exactly is jni used for ?
Baidu can find the official explanation I will not say more. My own understanding is two aspects, on the one hand mainly used in the implementation of a variety of complex algorithms, c high efficiency from needless to say, more importantly, so the crack is far more difficult than the APK, many companies rely on algorithms alive, no jni with them to die ~; On the other hand, Javanativeinterface, As a bridge between Java and C, we can throw a lot of things that Java code might not be able to do to the C level.
Ii. How to run up a project with JNI code
I use is AS2.1, the main study posture, so the default crossing environment has been tossing good, if not toss good Baidu a wash basin, learn a bit better. As now support for the NDK is still very moving low, but the compilation is very easy, so do it. Summary of the simple steps, not the same classmates do not spray, this is not the point:
1. Write a class and write the native method you need, like this:
Packagecom.amuro.ndkcompactdemo.chapter_1;/** * Created by Amuro on 2016/6/23. * * Public class chapter1jni{ Static{System.loadlibrary ("Ndk_compact"); } Public nativeStringStringfromjni(); Public native int Add(intAintb); Public nativeStringaddstring(String str); Public native int[]AddArray(int[] array);}
2. After writing, compile your code and make sure to pass. Then, with the termial of as comes into the engineering root directory, my root directory is this:
D:\DevelopAS\workspace\NDKCompactDemo
OK, then go to the following directory in the root directory:
D:\DevelopAS\workspace\NDKCompactDemo\app\build\intermediates\classes\debug
Then enter the command Javah-jni Com.amuro.ndkcompactdemo.chapter_1.Chapter1JNI
This will generate a. h header file in that directory. Do not ask me Javah is what also do not ask me h file is what, own Baidu. The generated header file code is as follows:
/* Don't EDIT this file-it are machine generated * /#include <jni.h>/ * Header for class COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI * /#ifndef _included_com_amuro_ndkcompactdemo_chapter_1_chapter1jni#define _INCLUDED_COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI#ifdef __cplusplusextern"C"{#endif/* * CLASS:COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI * METHOD:STRINGFROMJNI * Signature: () ljava/lang/st Ring */Jniexport jstringJnicallJava_com_amuro_ndkcompactdemo_chapter_11_chapter1jni_stringfromjni (jnienv *, jobject);/* * CLASS:COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI * Method:add * Signature: (II) I * *Jniexport JintJnicallJava_com_amuro_ndkcompactdemo_chapter_11_chapter1jni_add (JNIEnv *, Jobject, Jint, Jint);/* * CLASS:COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI * method:addstring * Signature: (ljava/lang/string; ) ljava/lang/string; */Jniexport jstringJnicallJava_com_amuro_ndkcompactdemo_chapter_11_chapter1jni_addstring (JNIEnv *, Jobject, jstring);/* * CLASS:COM_AMURO_NDKCOMPACTDEMO_CHAPTER_1_CHAPTER1JNI * Method:addarray * Signature: ([i) [I */Jniexport JintarrayJnicallJava_com_amuro_ndkcompactdemo_chapter_11_chapter1jni_addarray (JNIEnv *, Jobject, Jintarray);#ifdef __cplusplus}#endif#endif
3. Create a JNI folder under the Src/main directory of the project and copy the H file that you just generated.
4. Configure the Gradle
1) Add NDK configuration under Build.gradle of App module, complete Gradle file as follows:
Apply plugin:' Com.android.application 'Android {Compilesdkversion atBuildtoolsversion"23.0.2"Defaultconfig {ApplicationID"Com.amuro.ndkcompactdemo"Minsdkversion theTargetsdkversion atVersioncode1Versionname"1.0"ndk{ModuleName"Ndk_compact"Ldlibs"Log","Z","M" //Add dependent library file because there is log printing, etc.Abifilters"Armeabi","armeabi-v7a","x86"}} buildtypes {release {minifyenabledfalseProguardfiles Getdefaultproguardfile (' Proguard-android.txt '),' Proguard-rules.pro '}}}dependencies {Compile Filetree (dir:' Libs ', include: [' *.jar ']) Testcompile' junit:junit:4.12 'Compile' com.android.support:appcompat-v7:23.3.0 '}
The first one is your own so library name, the second one looks at the note, the third copy and paste is good
2) Add in Gradle.properties:
Android.usedeprecatedndk=true
Don't ask me why.
5. For the H file generated before, write your own source files, C or CPP, remember to include H file included.
6. Then you can compile and execute, it is not easy, as help us to the previous eclipse needed to write the Android.mk file to automation.
Third, use the jni you need to know some knowledge
1. Pointers and references
Java has the most complicated knowledge of C encapsulation, and back to C we have to pick them up again, remember that I was just learning is also tossing and turning, actually want to understand after really not complicated. If your knowledge of C is back to teacher Tam, it is recommended that you take a day or two to pick it up, and then turn around and find out that a lot of source code understanding is much easier. Here's an example, look at the code:
First define a structure body:
struct Student{ int age; char* name;};
Then define a pointer to it:
typedefconststruct Student* Stu;
And then how do we use it:
Func (stu* student) {printf ( "%d" , (*student) Age) ; printf ( "%d" , (**student). age) ;} int main () {struct student s = {ten, "amuro ", 100}; stu stu = &s ; printf ( "%d" , stu->age) ; printf ( "%d" , (*stu). Age) ; func (&stu) ;}
The results of the operation of the four printed out is 10. Probably explain:
Stu is a pointer to S, that is, Stu is the address of S, so Stu at the time of assignment, the right side must be an address value, and & is the address character.
There are two ways to take a value from a pointer, which is written in the code.
When a function passes a pointer, be very careful. The Func parameter is actually a pointer to Stu, which is a pointer to the cursor. So when you pass the value, you should pass the Stu address. And the function of the student save is the address of Stu, so *student is to take out the address of the Stu address of the saved S, this time can be taken to operate the value. Drawing a picture is a good idea for everyone:
This example is to facilitate the understanding of jnienv *env this thing, in fact, our own function to get the ENV is just the example of the student, so we want to invoke the method in env, this will be written: (*env)->methodname
The correspondence between the 2.Java standard class and the JNI interface
Figure I was directly stolen, anyway, the formula is the Java class before adding a J on it, and then the first letter changed to lowercase.
Where's 3.jni.h?
Many posts will be listed a bunch of JNI functions, see confused, in fact, as long as we find the source code, a lot of problems will be very easy to solve. The source of the jni.h is in the NDK package we downloaded. My address is:
D:\DevelopAS\asSDK\ndk-bundle\platforms\android-23\arch-arm\usr\include
All the methods are in the inside, and then according to the needs of the inside to find the good.
Here's what the document looks:
Http://docs.oracle.com/javase/7/docs/technotes/guides/jni
When I saw this dense document, I wanted to die.
4. Function signature
Very important, in the C-layer reflection, all need to pass this thing, Baidu can find a lot of detailed posts, I here to take its essence.
Note that this table is wrong, Long's signature is J, I was in the pit was dead, looked for a long time to find out!
For example,
public String dosomething (int A, string x, long[] b); The
Signature is: (iljava/lang/string;[ J) ljava/lang/string;
in parentheses is the argument list, note that non-native classes must precede plus l, followed by a return value. Semicolon must not forget!!!! The
can actually use the JAVAP command to do it, but the individual feel better than the understanding after their own handwriting, familiar with high efficiency. This is not to be discussed here.
What is
5.JNIEnv?
1) jnienv is a thread-dependent struct that represents the Java environment in which the thread is running;
2) JNIEnv and JAVAVM: Pay attention to distinguish the two concepts; The
–JAVAVM:JAVAVM is the representative of the Java Virtual machine in the JNI layer, with only one JNI globally;
–JNIENV:JAVAVM is represented in the thread, each of which has one, and there may be many jnienv in the JNI;
3) JNIEnv effect:
– Call Java functions: JNIEnv represents the Java Runtime environment, you can use JNIEnv to invoke code in Java;
– Manipulating Java objects: The incoming JNI layer of the Java object is the Jobject object, which requires the use of jnienv to manipulate the Java object;
4) jnienv Architecture
Thread-Related: jnienv is thread-related, i.e. there is a jnienv pointer in each thread, each jnienv is thread-specific, other threads cannot use jnienv in this thread, thread A cannot call the thread B's jnienv;
– The current thread is valid: JNIEnv only valid on the current thread, jnienv cannot be passed between threads, in the same thread, multiple calls to the JNI layer method, the incoming jnienv is the same;
– Local methods match multiple jnienv: local methods defined in the Java layer can be called on different threads, so different jnienv can be accepted;
5) JNIENV structure: The above code can be drawn, jnienv is a pointer to a thread-related structure, thread-related structure pointing to the JNI function pointer array, the array contains a large number of JNI function pointers, which point to the specific JNI function;
Iv. How to use JNI
This topic is too big, on my own summary, the more commonly used is nothing more than four kinds, one is the basic type of operation, one is a string, one is to manipulate our custom type, one is an array.
1. Common Core API Interface
Mom eggs, do form good egg pain, continue to use instead of it ...
Basically see the name can guess meaning, with the method name, want to know how to use, pass which parameters, to check the document or I just said jni.h source file is good.
2. Go back and use Eclipse.
After using as I really feel weak explosion, although the compilation of a lot of convenience. For complex NDK development, it's up to eclipse to write android.mk files and application.mk files yourself.
The following is a summary of the common configuration of these two files:
3. I can think of the most painful thing, is no code hint ~
Memory Tension Pile handwriting Code God, please take a detour.
Anyway at the beginning with as I am crazy, basically can not write code, write a line to check the jni.h's head file to see the method name and the definition of the parameters passed, but also can not debug, only to run up after the log or error, inefficient can not endure. So how to get familiar code hints, here are two ways to do it.
Method One:
1) You need a Microsoft VisualStudio, the version does not have to be too high, I use 2008, build a project, choose DLL Project.
2) from the previous Jni.h header file directory, copy the jni.h and another file called Jni_md.h, plus your own Javah generated header files to the studio project directory, like this:
Then import these header files into your project:
and then auto-prompt and then come out. Cheer up
There is no dying of various red line green lines.
3) Compiled DLL files are actually can be used (learn the operating system of children's shoes are known, DLL dynamic link library is actually windows so), here is a note, that is, if you are installing 64-bit Java, remember to change the VS compiler condition to x64, Otherwise compiled DLL file Java is impossible to parse. Configure the path of the DLL file you generated to the environment variable under path, and then write a Java program to use the load DLL. My configuration is this:
D:\VisualStudio\Projects\NDKTest\x64\Debug; (There is a NDKTest.dll file)
4) Write a Java program to test the JNI code, System.loadlibrary, the Lib name on the "Ndktest" is OK. This is suitable for the test algorithm class of JNI, after the success of the test directly to the Android program to use it. After all, VS is unmatched in support of C.
Method 2:eclipse Add Code hints
1) I believe this is what a lot of children's shoes want ~ to get this out it took me a whole day to toss out various environments and configurations, ORZ
2) Confirm that your eclipse has the CDT installed, if not, go to the official website to find it, mine is here:
Http://download.eclipse.org/tools/cdt/releases/juno
Note that this address is used in Eclipse's install new software, and do not open the page directly.
3) Download MinGW, install MinGW, configure MinGW, see Tutorial:
http://blog.csdn.net/hujingn/article/details/5849516
4) New C project, choose, remember the right must choose MinGW
5) Well, there has been familiar with the code interface, Stdio.h,stdlib.h can see the source, cool, but at this time there is no JNI source code, do not worry, right-click the project, the Ndk-bundle source address configuration in:
Look at the picture, I will not post. Configure complete confirmation OK.
6) Exciting time finally arrived, plus Jni.h's include, see Change Blue No, change is right. At this time we can directly F3 ~ Then we can copy our Javah generated header file, and then see the Picture:
This would like to see what the source code, are relaxed and happy, some small algorithm, but also in the following main function to test themselves.
Almost all of these things, the rest is to learn the use of various APIs, as a programmer this is the necessary skills. Kneeling for Google as quickly as possible to support the development of the NDK, such a toss is too painful. If you have a better and more excellent way, welcome message discussion ~
Just the sauce ~
Android NDK Development techniques and techniques summary and experience