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 to update the App to achieve a win-win situation for ASO and retention?

As a developer, the last thing you want to see is...

The future of wearable technology and its applications

Wearable technology has evolved rapidly over the ...

This is the entire process of a product from establishment to acquiring users!

In the early stages of entrepreneurship , from bu...

How did Zhang Xiaolong build the huge business empire of WeChat?

WeChat's business strategy has always been co...

Flowers and bees are a perfect match. What tools do they use to collect nectar?

A bee lands on a flower to collect nectar (Photo/...

Surprise! Windows 10 loves to spread your WiFi password

Windows 10's Wi-FiSense feature has a securit...

360 Mobile executives make their debut: Zhou Hongyi fights Lei Jun again

96 days after injecting US$409 million into Coolp...

10 marketing misunderstandings and 10 opportunities in 2020 (Part 2)

For marketing, 2020 was a year of challenges, but...

A guide to placing game ads on Toutiao today!

On Toutiao , there are 50 million people who play...

Understand brand communication and marketing in 3 sentences!

This tweet starts off by talking about disseminat...