小工具知识网

当前位置: 首页 > 行业知识 > Android Jni添加打印(C++打印)

行业知识

Android Jni添加打印(C++打印)

2026-11-10 21:53:43 来源:互联网转载

Android Jni添加打印(C++打印)

文章目录

  • Android Jni添加打印(C++打印)
    • 一、前言
    • 二、添加日志实现
      • 1、在某个类上面定义类型和方法
      • 2、把日志方法定义在.h文件中
      • 定义 myLog.h
      • 3、引用打印头文件的示例代码
        • (1) MainActivity.java 代码
        • (2) 另外一个cpp代码类和头文件
        • (3)jni native-lib.cpp代码类
        • (4)打印内容
        • 三、其他
          • 1、打印各种类型和示例
            • (1)整数类型:
            • (2)浮点数类型:
            • (3)字符类型:
            • (4)字符串类型:
            • (5)布尔类型:
            • 2、日志打印不出情况
            • 3、__android_log_write 和 __android_log_print 区别?
              • (1)参数形式:
              • (2)使���方式:

                一、前言

                Android Jni中添加日志打印其实就是C/C++日志打印

                ()

                Android环境的C/C++代码打印,可以添加相关头文件后,调用打印方法

                跟Android打印类似,也是有打印级别,I,D,W,E

                ()

                二、添加日志实现

                1、在某个类上面定义类型和方法

                网上一般做法,在某一个cpp类的上面写如下代码:

                #include  //添加头文件#define LOG_TAG "TstCPlus" //定义TAG#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

                在方法中使用即可:

                 LOGI("test"); int result = 100; LOGI("test result = %d", result);

                其他级别打印也是同理使用。

                上面的方法把定义都写在打印的定义都写在一个类里面了,如果多个类使用打印就不方便了,

                如果要多个类都能见到调用到就可以定义在.h头文件里面,其他类加入定义一下头文件调用到了。

                2、把日志方法定义在.h文件中

                定义 myLog.h

                #include #define LOG_TAG "TestCPlus"#define ANDROID_PLATFORM#ifdef ANDROID_PLATFORM   #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))   #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))   #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))   #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))   #else   #define LOGD(fmt, ...) printf(fmt"\n", ##__VA_ARGS__)   #define LOGI(fmt, ...) printf(fmt"\n", ##__VA_ARGS__)   #define LOGW(fmt, ...) printf(fmt"\n", ##__VA_ARGS__)   #define LOGE(fmt, ...) printf(fmt"\n", ##__VA_ARGS__)#endif#endif

                上面代码添加了是否Android平台的判断,如果觉得没必要可以直接去掉。

                DEBUG的值也可以设置成false,0就是false。

                在具体cpp文件中,可以重新定义TAG标签

                #include "myLog.h"#define LOG_TAG "TAG_NAME"

                3、引用打印头文件的示例代码

                (1) MainActivity.java 代码
                    String TAG = "MainActivity Java";    static {        System.loadLibrary("native-lib");    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i(TAG, "onCreate");        TextView tv = findViewById(R.id.sample_text);        tv.setText(stringFromJNI());    }    public native String stringFromJNI();
                (2) 另外一个cpp代码类和头文件
                //TestCPlus.cpp 代码#include "TestCPlus.h"#include "Androidlog.h"int TestCPlus::add(int parameter1, int parameter2) {    int result = parameter1 + parameter2;    LOGI("MainActivity jni c++ result = %d", result);//添加打印,但是没有定义TAG    return result;}//TestCPlus.h头文件代码class TestCPlus {//定义变量和方法private:    int number;public:    int add(int parameter1,int parameter2); //定义方法};
                (3)jni native-lib.cpp代码类
                #include #include #include "Androidlog.h"#include "TestCPlus.h"#define LOG_TAG "native-lib.cpp" //重新定义TAGextern "C" JNIEXPORT jstring JNICALLJava_com_demo_jnilog_MainActivity_stringFromJNI(        JNIEnv* env,        jobject /* this */) {    std::string hello = "Hello from C/C++";    LOGD("MainActivity jni c++ ");    int num= 100;    LOGI("MainActivity jni c++ ,num = %d", num);    TestCPlus *testCPlus;    int result =  testCPlus->add(2, 50);    LOGI("MainActivity jni c++ ,result = %d", result);    return env->NewStringUTF(hello.c_str());}
                (4)打印内容
                2024-02-29 15:07:40.706  I/MainActivity Java: onCreate2024-02-29 15:07:40.706  D/native-lib.cpp: MainActivity jni c++ 2024-02-29 15:07:40.706  I/native-lib.cpp: MainActivity jni c++ ,num = 1002024-02-29 15:07:40.706  I/TestLog: MainActivity jni c++ result = 522024-02-29 15:07:40.706  I/native-lib.cpp: MainActivity jni c++ ,result = 52

                可以看到未定义 LOG_TAG 的 TestCPlus.cpp文件打印的就是使用原本的TAG,定义了的,就是用新的TAG

                三、其他

                1、打印各种类型和示例

                在C++中,可以使用不同的格式化输出来打印各种数据类型。下面是一些常见的数据类型及其对应的打印格式:

                (1)整数类型:
                 int: 使用"%d"格式打印, 例如:`int num = 10; printf("%d", num);`  long: 使用"%ld"格式打印, 例如:`long num = 1000000; printf("%ld", num);`  short: 使用"%hd"格式打印, 例如:`short num = 5; printf("%hd", num);`
                (2)浮点数类型:
                 float: 使用"%f"格式打印, 例如:`float num = 3.14; printf("%f", num);` double: 使用"%lf"格式打印, 例如:`double num = 2.71828; printf("%lf", num);`
                (3)字符类型:
                char: 使用"%c"格式打印,例如:`char ch = 'A'; printf("%c", ch);`
                (4)字符串类型:
                char数组或指针:使用"%s"格式打印,例如:`char str[] = "Hello"; printf("%s", str);`参数的里面的jstring打印示例:Java_com_example_example_NativeClass_printString(JNIEnv* env, jobject obj, jstring str) {    const char* nativeString = env->GetStringUTFChars(str, NULL);    if (nativeString != NULL) {        LOGI("String from Java: %s\n", nativeString);        env->ReleaseStringUTFChars(str, nativeString);        //或者:        std::string hello = "Hello from C++";    LOGI("stringFromJNI hello = %s", hello.c_str());    }}
                (5)布尔类型:
                bool: 使用"%d"或"%s"格式打印,分别将true打印为1,false打印为0或者"true"和"false",例如:`bool flag = true; printf("%d", flag);`

                上面的打印printf在Android平台打印都替换成 LOGI 即可。

                2、日志打印不出情况

                如果在JNI的CPP文件中日志打印不出来,可能有以下几个原因:

                1. 缺少日志打印库:在CPP文件中,需要包含头文件 ``,并且使用 Android NDK 提供的日志库函数来进行打印。请确保你的CPP文件中正确包含了该头文件。2. 编译配置问题:在编译时,需要将日志库链接到你的JNI库中。在 Android.mk 或 CMakeLists.txt 文件中,确保添加了正确的链接库配置。示例:`LOCAL_LDLIBS += -llog`。3. 日志级别设置问题:检查你的日志打印语句中的日志级别参数,例如 `__android_log_print(ANDROID_LOG_DEBUG, "TAG", "Log message");`。确保日志级别设置正确,以便在运行时打印出来。4. 运行时过滤问题:在 Android Logcat 中,可能需要设置正确的过滤条件,以确保你的日志能够显示出来。请确保你在 Logcat 中设置了正确的标签过滤条件,以及你期望的日志级别过滤条件。

                如果以上步骤都确认无误,但仍然无法打印日志,可以检查一下日志打印语句是否被执行到,或者尝试在其他位置打印日志,以确定是否是特定位置的问题。另外,确保你的应用具有适当的权限来写入日志。

                如果问题仍然存在,建议提供更多的代码细节或错误信息,以便更好地理解问题并提供帮助。

                3、__android_log_write 和 __android_log_print 区别?

                两个方法都是log.h里面定义的方法,目前看,两种方式都是可以打印,但是区别有什么呢

                在Android的JNI开发中,__android_log_write和__android_log_print都是用于在native代码中打印日志的函数。它们的区别如下:

                (1)参数形式:
                 `__android_log_write`函数的参数形式为:`__android_log_write(int prio, const char *tag, const char *msg)`。 其中,`prio`表示日志的优先级,`tag`表示日志的标签,`msg`表示日志的内容。`__android_log_print`函数的参数形式为:`__android_log_print(int prio, const char *tag, const char *fmt, ...)`。 其中,`prio`和`tag`的含义与`__android_log_write`相同,而`fmt`是一个格式化字符串,后面可以是可变参数。

                第一种方式比较接近Java代码的打印,msg字符串里面要包含所有打印的信息。

                第二种就是c++的打印方式,可以输入多个参数。在cpp文件中一般都是使用第二种。

                (2)使用方式:
                 `__android_log_write`函数需要将日志内容作为字符串传入,可以直接调用该函数输出,例如:`__android_log_write(ANDROID_LOG_DEBUG, "TAG", "Log message");``__android_log_print`函数使用类似于`printf`函数的格式化字符串,可以传入多个参数,例如:`__android_log_print(ANDROID_LOG_DEBUG, "TAG", "Log message: %d", value);`

                总的来说,__android_log_write函数更直接,适合简单的日志输出;

                而__android_log_print函数更灵活,可以使用格式化字符串来输出带有变量值的日志信息。

                实际使用中,可以根据需要选择合适的函数来打印日志。

上一篇:编写调查问卷的JavaScript代码全攻略,打造吸引人的调查体验!

下一篇:switch怎么连不到服务器?