Android Studio NDK Development

Source: Internet
Author: User

Android Studio NDK Development

I used to develop NDK In the Eclipse environment. Today, I tried to use Android Studio for configuration. The result is actually a pitfall everywhere. Now let's summarize:

1. Steps

1. First create MainActivity and add the native method:

package com.jackie.hellondk;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {    public native String getStringFromNative();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}
Note: I used AppCompatActivity under the v7 compatibility package. This knowledge may be used when compiling the header file below. Then, you must click the Green Arrow below to make project, and ensure that the. class file is generated.

 

2. Create a jni directory under the main directory to put the header file. You can use the following method:

3. Compile the header file

Enter the root directory of the project in Terminal. for Android Studio, switch to app \ src \ main and directly execute the following command according to the online statement:

Javah-d jni com. jackie. hellondk. MainActivity (-d jni specifies that the header file is generated in the jni directory. If the jni folder is not created in step 2, it is automatically created)

Obviously, MainActivity cannot be found. class bytecode file, and then specify MainActivity according to the method on the official website. class path, in Android Studio, all. the class files are generated under app \ build \ intermediates \ classes \ debug. Therefore, run the following command:

Javah-classpath... \ build \ intermediates \ classes \ debug-d jni com. jackie. hellondk. MainActivity

Why? This is because the MainActivity above inherits AppCompatActivity. This class is in the compatible package of Android v7, so we also need to add the compatible package of v7 to classpath:

Javah-classpath D: \ DevTools \ studio_sdk \ extras \ android \ support \ v7 \ appcompat \ libs \ android-support-v7-appcompat.jar ;.. \.. \ build \ intermediates \ classes \ debug-d jni com. jackie. hellondk. mainActivity

Similarly, you also need to add the v4 compatibility package to classpath:

Javah-classpathD: \ DevTools \ studio_sdk \ extras \ android \ support \ v4 \ android-support-v4.jar; D: \ DevTools \ studio_sdk \ extras \ android \ support \ v7 \ appcompat \ libs \ android-support-v7-appcompat.jar ;.. \.. \ build \ intermediates \ classes \ debug-d jni com. jackie. hellondk. mainActivity

The language is speechless. It is a pitfall everywhere. Continue to add android. jar to classpath!

Javah-classpathD: \ DevTools \ studio_sdk \ platforms \ android-23 \ android. jar; D: \ DevTools \ studio_sdk \ extras \ android \ support \ v4 \ android-support-v4.jar; D: \ DevTools \ studio_sdk \ extras \ android \ support \ v7 \ appcompat \ libs \ android-support-v7-appcompat.jar ;.. \.. \ build \ intermediates \ classes \ debug-d jni com. jackie. hellondk. mainActivity

Finally, the header file is successfully generated as follows:

Note: The reason why I need to add so many classpath above is that I use AppCompatActivity. Generally, I only need. jar and. add the class directory (app \ build \ intermediates \ classes \ debug) to classpath. In actual development, if you cannot find the class, add classpath on your own. Note that the classpath is separated by semicolons. In addition, if you think it is too troublesome to knock so many commands each time, you can also configure the classpath above to the system's environment variables. As for how to get it, I believe everyone is OK! This is not detailed here.

4. Implement the native METHOD

Create a hello. c file in the jni directory to implement the methods in the header file:

#include 
 
  #include 
  
   #include "com_jackie_hellondk_MainActivity.h"JNIEXPORT jstring JNICALL Java_com_jackie_hellondk_MainActivity_getStringFromNative  (JNIEnv *env, jclass jclass) {  return (*env)->NewStringUTF(env, "Hello from JNI");}
  
 
5. Compile the Android. mk File
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := helloLOCAL_SRC_FILES := hello.cinclude $(BUILD_SHARED_LIBRARY)

 

6. Compile the dynamic link library so. Be sure to switch to the jni directory. Before Running ndk-build, you must configure the environment variable.

The generated directory is as follows:

6. Reference

package com.jackie.hellondk;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    static {        System.loadLibrary("hello");    }    TextView mTextView;    public native String getStringFromNative();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTextView.setText(getStringFromNative());    }}
The following error occurs during compilation:

Add the following sentence to gradle. properties:

Android. useDeprecatedNdk = true

Continue compilation with the following error:

The configuration is as follows:

After compilation, the java. lang. UnsatisfiedLinkErrorcouldn't find libhello. so error still occurs after the installation is complete.

Modify the build. gradle configuration and add the following code in defaultConfig:
ndk {     moduleName "hello"     abiFilters "armeabi", "armeabi-v7a", "x86" }
Note that the moduleName must be the same as the name defined in System. loadLibrary and Android. mk.

The last run finally saw the long-overdue interface!

After taking a lot of detours, it is really a trap everywhere. Make a record and hope to help you. Finally, we use ndk-build to compile and generate the dynamic link library libhello. so, and then load it in Java through loadLibrary. In the actual development process, you can skip this step of ndk-build. After the jni program is developed, the program runs directly. Android Studio will automatically help us compile the dynamic link library and test the program successfully!

Ii. Print log information

I believe that many people need to output logs when learning Android JNI programming. Therefore, modify the hello. c file as follows:

# Include
 
  
# Include
  
   
# Include "com_jackie_hellondk_MainActivity.h" # include # define TAG "Jackie" # define LOGV (...) _ android_log_print (ANDROID_LOG_VERBOSE, TAG, _ VA_ARGS _) JNIEXPORT jstring JNICALL partition (JNIEnv * env, jclass) {LOGV ("log from native "); /*** C Language */return (* env)-> NewStringUTF (env, "Hello from JNI "); /*** C ++ * return env-> NewStringUTF ("Hello from JNI ");*/}
  
 
Then modify the Android. mk file:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := helloLOCAL_SRC_FILES := hello.c# for loggingLOCAL_LDLIBS    += -lloginclude $(BUILD_SHARED_LIBRARY)

During runtime, the error of undefined reference to '_ android_log_print' always occurs. Some may be surprised that Android. mk file and android/log. h. The header files are introduced. How can this problem be solved?

Android. mk of Android Studio is automatically generated, and even modification is useless. In actual Android Studio, Android. mk is generated based on the gradle file, so you need to modify the gradle file. If gradle is not modified, an error is reported when _ android_log_print is directly used.

Error:(36) undefined reference to '__android_log_print'

Now you only need to add the following code in module build. gradle to output Log: 1

Add the arrow!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.