Getting started with Android Studio jni development——Just look at me!

Getting started with Android Studio jni development——Just look at me!

This article records the basic configuration and introductory tutorials for jni development in Android Studio. It was difficult to use eclipse to configure the ndk environment. Now it is basically transformed to AS. This article is to help the novice students who need help to avoid detours ☺

1. Environment Configuration

The main thing you need to configure is NDK (Native Development Kit). Now Android studio is very convenient and can be downloaded with one click: file → setting → find the following path as shown in the screenshot → select NDK → confirm the application download

After the installation is complete, you can start

2. jni hello world!

1. Create a new project

Create a new app and test jni development

2. Set up support for jni

Open gradle.properties and add:

  1. android.useDeprecatedNdk= true  

Open local.properties and add:

  1. ndk.dir = NDK path

Finally, open appbuild.gradle and add ndk configuration under android/defaultConfig

  1. apply plugin: 'com.android.application'  
  2.  
  3. android {
  4.  
  5. compileSdkVersion 25
  6.  
  7. buildToolsVersion "25.0.0"  
  8.  
  9. defaultConfig {
  10.  
  11. applicationId "com.lilei.testjni"  
  12.  
  13. minSdkVersion 15
  14.  
  15. targetSdkVersion 25
  16.  
  17. versionCode 1
  18.  
  19. versionName "1.0"  
  20.  
  21. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"  
  22.  
  23. ndk {
  24.  
  25. moduleName "JNISample"  
  26.  
  27. }
  28.  
  29. }
  30.  
  31. buildTypes {
  32.  
  33. release {
  34.  
  35. minifyEnabled false  
  36.  
  37. proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro'  
  38.  
  39. }
  40.  
  41. }
  42.  
  43. }
  44.  
  45. dependencies {
  46.  
  47. compile fileTree(dir: 'libs' , include: [ '*.jar' ])
  48.  
  49. androidTestCompile( 'com.android.support.test.espresso:espresso-core:2.2.2' , {
  50.  
  51. exclude group : 'com.android.support' , module: 'support-annotations'  
  52.  
  53. })
  54.  
  55. compile 'com.android.support:appcompat-v7:25.3.1'  
  56.  
  57. compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'  
  58.  
  59. testCompile 'junit:junit:4.12'  
  60.  
  61. }

moduleName indicates the name of the compiled so file

3. Create a new interface class for Java to access the C layer

Create a Jni tool class and define the interface function. Use native as the function keyword (static can be used or not)

  1. package com.lilei.testjni;
  2.  
  3. /**
  4.  
  5. * Created by lilei on 2017/3/29.
  6.  
  7. */
  8.  
  9. public class JniUtils {
  10.  
  11. public   static native String getJniString();
  12.  
  13. }

The getJniString() method is the function that interacts with the C layer

4. Generate header file

"make-project" compilation completed

Open the terminal and run

After running successfully, open app/build/intermediates/classes/debug/ and you can find the compiled header file "com_lilei_testjni_JniUtils.h". It is not difficult to find that the header file name is composed of the original registration name + class name

  1. cd app/build/intermediates/classes/debug/
  2.  
  3. javah com.lilei.testjni.JniUtils

5. Create a folder for jni development

Click the app folder, New → Folder → JNI Folder, and select the main folder. After the generation is successful, a jni folder will appear in the main directory.

Find the header file just generated and copy it to the jni folder (remember to close the terminal just used, otherwise it cannot be copied)

Now that we have the header file, we can create a C++ file in the jni directory for development and name it the same as the header file.

Write the code that defines the function in the C++ file

  1. #include "com_lilei_testjni_JniUtils.h"  
  2.  
  3. JNIEXPORT jstring JNICALL Java_com_lilei_testjni_JniUtils_getJniString
  4.  
  5. (JNIEnv *env, jclass) {
  6.  
  7. // new a string, return Hello World
  8.  
  9. return env -> NewStringUTF( "Hello World" );
  10.  
  11. }

6. Java layer loading so

Back to JniUtils, add

  1. static {
  2.  
  3. System.loadLibrary( "JNISample" );
  4.  
  5. }

7. Run

Calling jni function

  1. package com.lilei.testjni;
  2.  
  3. import android.support.v7.app.AppCompatActivity;
  4.  
  5. import android.os.Bundle;
  6.  
  7. import android.util.Log;
  8.  
  9. public class MainActivity extends AppCompatActivity {
  10.  
  11. @Override
  12.  
  13. protected void onCreate(Bundle savedInstanceState) {
  14.  
  15. super.onCreate(savedInstanceState);
  16.  
  17. setContentView(R.layout.activity_main);
  18.  
  19. Log.i( "Jni" , JniUtils.getJniString());
  20.  
  21. }
  22.  
  23. }

So far, jni's Hello World has been successfully run.

3. Generate so file

The previous article introduces how to run C++ programs, but in actual development, most of the development is done by encapsulating and compiling so files, just like the jar package in java.

1. Configure NDK environment variables

Find the file directory of the NDK package installed by Android Studio (E:AndroidStudioSDKSDKndk-bundle) and add it to the system environment variables

2. Create a new mk file

Create a new Android.mk in the jni directory

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := JNISample
  6.  
  7. LOCAL_SRC_FILES := com_lilei_testjni_JniUtils.cpp
  8.  
  9. include $(BUILD_SHARED_LIBRARY)

Create a new Application.mk file in the jni directory

  1. APP_STL := gnustl_static
  2.  
  3. APP_CPPFLAGS := -frtti -fexceptions -std=c++0x
  4.  
  5. APP_ABI := armeabi-v7a
  6.  
  7. APP_PLATFORM := android-18

3. Compile and generate so

Open the terminal and cd to the jni directory

Call ndk-build to start compiling so

  1. ndk-build

If the operation is correct, it will be as shown in the figure

After the operation is successful, you will see that there are more folders libs and obj under the main folder, which contain the generated so files of various CPUs.

There are so files in both libs and obj. Google explains the difference between the two as follows: As part of the build process, the files in the libs folder have been stripped of symbols and debugging information. So you'll want to keep two copies of each of your .so files: One from the libs folder to install on the Android device, and one from the obj folder to install for GDB to get symbols from. In other words, the library generated in the libs directory is stripped of symbol tables and debugging information, while the library under obj has debugging information.

At this point, the introduction to jni development has been completed

<<:  Gradle for Android Part 2 (Getting Started with Build.gradle)

>>:  Gradle for Android Part 3 (Dependency Management)

Recommend

How much does it cost to be an agent of a points app in Ningbo?

How much does it cost to be an agent of a points ...

Foreign media predicts that Alibaba will acquire Sina Weibo within six months

[[152728]] Alibaba Group, which has been imitatin...

Facing a sales ban in China: Is Apple on its way to the end of the patent war?

On the evening of December 10th, Beijing time, Qu...

How to choose channels for app soft promotion?

There is another big pitfall in App soft promotio...

Big data interprets new trends in Apple App Store

This article mainly interprets the new trends of ...

5,000 words of practical operation tips to help you become an operation expert

Before reading this article, please think about: ...

Please remember her name again - Happy 91st birthday Tu Youyou!

She discovered artemisinin, which can effectively...