[Android beginner] Getting started with NDK, using the dig method, ndk

Source: Internet
Author: User

[Android beginner] Getting started with NDK, using the dig method, ndk

This article is a self-review. Do not be surprised if the content is repeated.

How does one call java code in the Custom underlying C of android applications? This is a self-review plan.

First, I have to create a demo with the following structure:


1. Create an interface class NativeDataProvider. Its function is to call the c method and then call back the java method.

Public class NativeDataProvider {static final String TAG = "NativeDataProvider"; private Context context; public NativeDataProvider (Context context) {this. context = context;} // call the code public native void callCCode () in C; public native int callCAdd (int I, int j); public native void callCPrintString (); // call org. jan. ndk. example. nativeDataProvider No parameter method helloFrmJavapublic void helloFromJava () {Log. I (TAG, "hello From java! "); Toast. makeText (context, "hello from java", Toast. LENGTH_SHORT ). show () ;}// call the public void printString (string str) {Log. I (TAG, "[from java]:" + str); Toast. makeText (context, "printString-> str:" + str, Toast. LENGTH_SHORT ). show () ;}// call the public int add (int I, int j) {int result = I + j; Log. I (TAG, "result is" + result); Toast. makeText (context, "add-> result =" + result, Toast. LENGTH_SHORT ). show (); return result ;}}

2. Create Android. mk

LOCAL_PATH: = $ (call my-dir) include $ (CLEAR_VARS) LOCAL_MODULE: = jni_demoLOCAL_SRC_FILES: = jni_demo.c # Add the log library LOCAL_LDLIBS + =-llog include $ (BUILD_SHARED_LIBRARY)
3. Create the jni, that is, the c code. Create the NativeDataProvider header file first, go to the project directory/bin/classes, and call Javah org. jan. ndk. example. NativeDataProvider

Org_jan_ndk_example_NativeDataProvider.h is generated.

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class org_jan_ndk_example_NativeDataProvider */#ifndef _Included_org_jan_ndk_example_NativeDataProvider#define _Included_org_jan_ndk_example_NativeDataProvider#ifdef __cplusplusextern "C" {#endif/* * Class:     org_jan_ndk_example_NativeDataProvider * Method:    callCCode * Signature: ()V */JNIEXPORT void JNICALL Java_org_jan_ndk_example_NativeDataProvider_callCCode  (JNIEnv *, jobject);/* * Class:     org_jan_ndk_example_NativeDataProvider * Method:    callCAdd * Signature: (II)I */JNIEXPORT jint JNICALL Java_org_jan_ndk_example_NativeDataProvider_callCAdd  (JNIEnv *, jobject, jint, jint);/* * Class:     org_jan_ndk_example_NativeDataProvider * Method:    callCPrintString * Signature: ()V */JNIEXPORT void JNICALL Java_org_jan_ndk_example_NativeDataProvider_callCPrintString  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

Signature :() V is similar to method Signature.

For example:

Har * classname = "org/jan/ndk/example/NativeDataProvider ";
Jclass dpclazz = (* env)-> FindClass (env, classname );

This is to get the class object through the jnienv pointer.


JmethodID methodID = (* env)-> GetMethodID (env, dpclazz, "helloFromJava", "() V ");

GetMethodID indicates obtaining the defined method from java. The second parameter is the class object, the third parameter is the method name, and the fourth parameter is the method Signature (you can view Signature from the file)

View the method signature method: Enter the project \ bin \ classes, command: javap-s org. jan. ndk. example. NativeDataProvider

"() V" means that there is no parameter in the brackets, that is, there is no input parameter, and V means that there is no return value for void.



The following is the main code of C (For details, refer to the notes ):

# Include "org_jan_ndk_example_NativeDataProvider.h" # include <string. h> # include <android/log. h> # define LOG_TAG "System. out "# define LOGD (...) _ android_log_print (ANDROID_LOG_DEBUG, LOG_TAG, _ VA_ARGS _) # define LOGI (...) _ android_log_print (ANDROID_LOG_INFO, LOG_TAG, _ VA_ARGS _) JNIEXPORT void JNICALL encode (JNIEnv * env, jobject obj) {// call NativeDataProvi HelloFromJava () method in der object // obtain an object, obtain the method in the object, and call the obtained method LOGI ("in code"); // NativeDataProvider complete class name org. jan. ndk. example. optional * classname = "org/jan/ndk/example/NativeDataProvider"; jclass dpclazz = (* env)-> FindClass (env, classname); if (dpclazz = 0) LOGI ("org. jan. ndk. example. nativeDataProvider. class not find !!! "); ElseLOGI (" org. jan. ndk. example. NativeDataProvider. class find !!! "); // Use jni. the GetMethodID method provided in h, get jmethodID, input the parameter ① JNIEnv pointer ② Class Object ③ method name ④ method signature, here the method name and method signature determine a method, the method signature is the unique identifier of the return value and parameter of the method. // parameter Introduction: The second parameter is the Class object, the third parameter is the method name, and the fourth parameter is the method signature, obtain the call's methodjmethodID methodID = (* env)-> GetMethodID (env, dpclazz, "helloFromJava", "() V"); if (methodID = 0) LOGI ("method helloFromJava not find !!! "); ElseLOGI (" method helloFromJava find !!! ");/** Call method void (* CallVoidMethod) (JNIEnv *, jobject, jmethodID ,...); * parameter Introduction: The following... it is a variable parameter. If the void method of the returned value has parameters, the parameters are sorted in order */LOGI ("before call method"); (* env)-> CallVoidMethod (env, obj, methodID); LOGI ("after call method");} JNIEXPORT void JNICALL encode (JNIEnv * env, jobject obj) {// call helloFromJava () in the DataProvider object () method // obtain an object, obtain the method in the object, and call the obtained method L OGI ("in code"); // NativeDataProvider full class name org. jan. ndk. example. optional * classname = "org/jan/ndk/example/NativeDataProvider"; jclass dpclazz = (* env)-> FindClass (env, classname); if (dpclazz = 0) LOGI ("class not find !!! "); ElseLOGI (" class find !!! "); // Parameter description: The second parameter is the Class object, the third parameter is the method name, and the fourth parameter is the method signature, obtain the call's methodjmethodID methodID = (* env)-> GetMethodID (env, dpclazz, "printString", "(Ljava/lang/String;) V "); if (methodID = 0) LOGI ("method not find !!! "); ElseLOGI (" method find !!! ");/** Call method void (* CallVoidMethod) (JNIEnv *, jobject, jmethodID ,...); * parameter Introduction: The following... it is a variable parameter. If the void method of the returned value has parameters, the parameters are sorted in order */LOGI ("before call method"); (* env)-> CallVoidMethod (env, obj, methodID, (* env)-> NewStringUTF (env, "printString method callback success !! "); LOGI (" after call method ");}/** actual development situation * C code engineer gives us first. h first. c. We only need. h. Then you can use the method */JNIEXPORT jint JNICALL Java_org_jan_ndk_example_NativeDataProvider_callCAdd (JNIEnv * env, jobject obj, jint a, jint B) {// call the helloFromJava () method in the DataProvider object // obtain an object, obtain the method in the object, and call the obtained method LOGI ("in code test_add => "); // NativeDataProvider full class name org. jan. ndk. example. nativeDataProviderchar * classname = "o Rg/jan/ndk/example/NativeDataProvider "; jclass dpclazz = (* env)-> FindClass (env, classname); if (dpclazz = 0) LOGI ("class not find !!! "); ElseLOGI (" class find !!! "); // Parameter description: The second parameter is the Class object, the third parameter is the method name, and the fourth parameter is the method signature, obtain the call's methodjmethodID methodID = (* env)-> GetMethodID (env, dpclazz, "add", "(II) I"); if (methodID = 0) LOGI ("method not find !!! "); ElseLOGI (" method find !!! ");/** Call method void (* CallVoidMethod) (JNIEnv *, jobject, jmethodID ,...); * parameter Introduction: The following... is a variable parameter. If the void method of the returned value has parameters, the parameters are arranged in order */return (* env)-> CallIntMethod (env, obj, methodID,, B );}

4. Compile jni and manually execute ndk-build in the demo directory.

5. android code:

public class MainActivity extends ActionBarActivity {private static final String TAG = "MainActivity";private static NativeDataProvider ndp;static{System.loadLibrary("jni_demo");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ndp = new NativeDataProvider(this);if (savedInstanceState == null) {getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}/** * A placeholder fragment containing a simple view. */public static class PlaceholderFragment extends Fragment implements OnClickListener {private Button callVoidMethod, callStringMethod, callIntMethod;public PlaceholderFragment() {}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment_main, container,false);callVoidMethod = (Button) rootView.findViewById(R.id.call_void_method_btn);callStringMethod = (Button) rootView.findViewById(R.id.call_string_parameter_method);callIntMethod = (Button) rootView.findViewById(R.id.call_int_parameter_method);callVoidMethod.setOnClickListener(this);callStringMethod.setOnClickListener(this);callIntMethod.setOnClickListener(this);return rootView;}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.call_void_method_btn:ndp.callCCode();break;case R.id.call_string_parameter_method:ndp.callCPrintString();break;case R.id.call_int_parameter_method:ndp.callCAdd(2,3);break;}}}}

The implementation result is as follows:



Sample Code download: Please open Ruyi door to download




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.