Android NDK Development (III)-Common Errors and LOG usage, androidndk

Source: Internet
Author: User

Android NDK Development (III)-Common Errors and LOG usage, androidndk

Reprinted please indicate the source:Http://blog.csdn.net/allen315410/article/details/41826511

Android NDK development often has unexpected errors due to some factors. Many times debugging these errors is more complicated than debugging Java code. On the one hand, there are many causes of errors, on the other hand, NDK development involves writing C/C ++ code, which many programmers are not familiar. This blog will summarize some problems that often occur during NDK development and try to provide some correct solutions to help you quickly locate and change errors during development, of course, errors are diverse and it is difficult to sum up all the errors. Here we only take one note. After an error is found in NDK development or an error is solved, I will record it here. It will be nice if it is accumulated over time!

Common Errors and Solutions
1. The Android. mk file does not exist.

Error Description: Android NDK: Your APP_BUILD_SCRIPT points to an unknown file:./jni/Android. mk
/Cygdrive/e/ndk/android-ndk-r10d/build/core/add-application.mk: 199: *** Android NDK: Aborting .... Stop.

Solution: If this error is reported, check whether the Android. mk file exists in the jni directory under the project directory or whether the Android. mk file name is incorrect.


2. An error occurred while configuring the Android. mk file.


Error Description:/cygdrive/e/ndk/android-ndk-r10d/build/core/build-shared-library.mk: 23: *** Android NDK: Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY in jni/Android. mk. Stop.

Solution: Check the configuration information of the Android. mk file. Missing LOCAL_MODULE indicates that the LOCAL_MODULE configuration is incorrect. view and modify the configuration.


3. C language code error


Error Description: [armeabi] Compile thumb: Hello <= Hello. c
Jni/Hello. c: In function 'java _ com_example_ndk_MainActivity_java_1From_1JNI ':
Jni/Hello. c: 17: 9: warning: division by zero [-Wdiv-by-zero]
Int I = 5/0;
^
[Armeabi] SharedLibrary: libHello. so
[Armeabi] Install: libHello. so => libs/armeabi/libHello. so

Solution: errors are usually reported in C language. We can locate Errors Based on the LOG on cygwin.


4. C code library not found in Java code
Error Description: AndroidRuntime (1171): java. lang. unsatisfiedLinkError: Couldn't load Hello1 from loader dalvik. system. pathClassLoader [DexPathList [[zip file "/data/app/com.example.ndk-1.apk"], nativeLibraryDirectories = [/data/app-lib/com. example. ndk-1,/system/lib]: findLibrary returned null

Solution: This indicates that the Java code library name is rough when loading the C code library. Correct the name in the java layer.


5. The C-code function signature is incorrect.


Error Description: java. lang. UnsatisfiedLinkError: Native method not found: com. example. ndk. MainActivity. java_From_JNI :() Ljava/lang/String;

Solution: Native method not found. This should not be difficult. At first glance, we can see that the function signature in C language is wrong.


6. ndk version Problems


Error Description: Android NDK: WARNING: APP_PLATFORM android-19 is larger than android: minSdkVersion 8 in./AndroidManifest. xml
[Armeabi] Compile thumb: Hello <= Hello. c
[Armeabi] SharedLibrary: libHello. so
[Armeabi] Install: libHello. so => libs/armeabi/libHello. so

Solution: This is just a warning. If it is not processed, the program will run as well. This warning is caused by the current ndk version> minSdkVersion in the project. If you want to remove this warning, change the minimum version supported by minSdkVersion to the same version number as the ndk version number. Of course, this is a silly practice, however, we can use the earlier version of ndk for compilation, which is not very good. The following is a good solution:

1. Create a new file under the project directory jni. The file name is Application. mk.

2. Add the following sentence to the Application. mk file:

APP_PLATFORM := android-8

3. Save the project, compile it, and you will see that the warning is gone.


7. When the javah command is used to generate the function signature, the class file cannot be found.


Error Description: Error: unable to access android. app. Activity
Android. app. Activity Class file not found

Solution: The specific cause of this error should not find the Java bytecode file where the corresponding native method is located, but I do have the correct path here or report an error, which is strange, I don't know if it is a BUG in Eclipse. This problem can be solved in this way. Since it cannot be switched to the \ bin \ classes directory, switch to the project directory \ src directory, and then javah. h header file. I don't know why. It is feasible for me to test it.

Tip: Obtain the header file of the local method
Jdk6.0: run the following command in the bin \ classes directory of the Android project: javah package name + class name
Jdk7.0: run the following command under the src directory of the Android project: javah package name + class name


8. Chinese garbled characters

Error Description: In ndk development, a Chinese string is often returned to the Java code in the C language code. When it is occasionally called in Java, Chinese characters are garbled in the program results, or, even worse, the program crashes directly, and checking the Log logs also shows garbled characters.

Solution:

The reason for Chinese garbled characters is that the English C language file storage format is not the UTF-8 format, or the whole project is not the UTF-8 format, because the C language jni when passing the string using the UTF-8 encoding, this can be done in (* env)-> NewStringUTF (env, "hello jni! ") As you can see, NewStringUTF (env, char *) indicates that the returned string is a UTF-8 encoded string. So when we create a project, or create a new C language code file, you need to specify the project code for the UTF-8 or C language code File Save format is UTF-8.


9. unmapped characters encoded in GBK


Error Description: Non- able characters encoded in GBK.

Work und: the cause of this error is that java's collections are not specified when javah is used, in which case the compiler automatically compiles Based on windows default encoding (GBK), while Java supports the collections set of UTF-8. To solve this problem, specify a sequence set for the compiler when executing the javah command, and use the parameter-encoding sequence set of the javah command,



LOG usage

The above lists some problems and solutions that often occur during ndk development, but not listed. The most common error is that errors occur in the C language code, which is not a good solution, in addition, there are various problems, which can be addressed in specific cases. It is known that Google provides the LOG output function in the SDK to facilitate programmer debugging when developing Android programs using Java, which is used by programmers to output logs in the program. Fortunately, Google also provides a similar LOG Mechanism in the NDK to help locate native-Layer Code errors. Next we will try to use this LOG mechanism.

Under the ndk decompression directory, platforms \ android-8 \ arch-arm \ usr \ include \ android has a log. h header file, this log. the header file of h is used to manage LOG output in C language code. The Code is as follows:

#ifndef _ANDROID_LOG_H#define _ANDROID_LOG_H#include <stdarg.h>#ifdef __cplusplusextern "C" {#endif/* * Android log priority values, in ascending priority order. */typedef enum android_LogPriority {    ANDROID_LOG_UNKNOWN = 0,    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */    ANDROID_LOG_VERBOSE,    ANDROID_LOG_DEBUG,    ANDROID_LOG_INFO,    ANDROID_LOG_WARN,    ANDROID_LOG_ERROR,    ANDROID_LOG_FATAL,    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */} android_LogPriority;/* * Send a simple string to the log. */int __android_log_write(int prio, const char *tag, const char *text);/* * Send a formatted string to the log, used like printf(fmt,...) */int __android_log_print(int prio, const char *tag,  const char *fmt, ...)#if defined(__GNUC__)    __attribute__ ((format(printf, 3, 4)))#endif    ;/* * A variant of __android_log_print() that takes a va_list to list * additional parameters. */int __android_log_vprint(int prio, const char *tag,                         const char *fmt, va_list ap);/* * Log an assertion failure and SIGTRAP the process to have a chance * to inspect it, if a debugger is attached. This uses the FATAL priority. */void __android_log_assert(const char *cond, const char *tag,  const char *fmt, ...)    #if defined(__GNUC__)    __attribute__ ((noreturn))    __attribute__ ((format(printf, 3, 4)))#endif    ;#ifdef __cplusplus}#endif#endif /* _ANDROID_LOG_H */
It doesn't matter if the above code doesn't understand it. We just need to know how to use it.

1. reference the header file of log. h In the C language code, and pre-define LOG_TAG to mark the Tag Name and pre-define the output rule:

2. Use the predefined name above to define the LOG output content

# Include <stdio. h> # include <jni. h> # include "com_example_ndk_MainActivity.h" # include <android/log. h> # define LOG_TAG "System. out. c "# 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 jstring JNICALL partition (JNIEnv * env, jobject obj) {return (* env)-> NewStr IngUTF (env, "hello jni! ");}/** Class: com_example_ndk_MainActivity * Method: java_From_JNI * Signature: () Ljava/lang/String; */JNIEXPORT jstring JNICALL evaluate (JNIEnv * env, jobject obj) {LOGI ("function called"); LOGI ("array init"); char c1 [3] = {'A', 'B', 'C '}; char c2 [2] = {'D', 'E'}; LOGI ("array init finish"); LOGI ("copy array"); strcat (c1, c2 ); // place the content of c2 behind c1. The length of c1 must be greater than that of c2 LOGI ("copy array finish"); return (* env)-> NewStringUTF (env, "hello_jni __");}
In the above Code
#include <android/log.h>#define LOG_TAG "System.out.c"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
Must be added, telling the compiler that logs need to be output, and the log tag is "System. out. c ", and predefine LOGD (...) indicates the Debug output, LOGI (...) info output. Then, you can use LOGD and LOGI in the C language theme code to pass strings. Note that the passed strings must use English characters and do not support Chinese characters.

3. Configure LOG output in the Android. mk file.

    LOCAL_PATH := $(call my-dir)    include $(CLEAR_VARS)    LOCAL_MODULE    := Hello    LOCAL_SRC_FILES := Hello.c        LOCAL_LDLIBS += -llog    include $(BUILD_SHARED_LIBRARY)
Note: Just use LOCAL_LDLIBS + =-llog, but it must be added before include $ (BUILD_SHARED_LIBRARY.

4. recompile the code and run it to check the effect.


Okay, we can filter out System in Logcat. out. c TAG, you can see that the program stops after the output copy array, indicating LOGI ("copy array"); strcat (c1, c2) below; an error occurs, here, we need to modify the errors in the Code so that the program can be correctly executed. Is it very convenient? Try it!


Download the source code here


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.