Android中关于JNI 的学习(五)在C文件里使用LogCat
Log是开发过程中。对于我们调试程序非常重要的一个工具,有非常多时候,我们正是通过Log才干够看清楚程序是不是真的依照我们想像中的模式在跑,从而定位到问题所在的地方。而在Android开发中,毫无疑问,要是没有了logcat。我们调试程序的时候,就会痛苦死。
在NDK的开发中,虽然我们是利用C/C++来开发程序的,然后通过载入共享库的方法来调用C/C++程序,Android也提供了一套方法。能够让我们在LogCat中看到在C/C++代码中的数据流向,帮我们定位问题。
这一篇文章就简单地来说一下。怎样在JNI层使用log工具。
回到我们之前的demo中。我们在程序中为了查看在JNI层某个数的值是否被改变了,我们特意加入了以下的log:
LOGI("before change testval = %d", val);
val = val + 1;
LOGI("after change testval = %d", val);
当程序在手机上执行的时候,我们就能够在LogCat中看到以下的记录:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlubWlhbnNoZW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
这说明了,在C/C++中相同是能够利用log工具来调试的(事实上这是废话,由于Android中Log的实现本来就是通过JNI层。由C++实现的。)
以下我们就来说一下,怎样在C/C++文件里加入log吧。
1)在C/C++文件里。要加入log的引用文件,如以下第2行:
#include "com_lms_jni_ParamTransferTest.h"
#include <android/log.h>
#include <jni.h>
在这里,我们会引用android/log.h头文件,而log.h头文件定义了几个log函数,例如以下:
/*
* 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);
2)引入log.h头文件之后,我们能够在C/C++中直接使用__android_log_print方法,只是老这样使用,就太麻烦了,所以我们能够又一次定义一下。例如以下:
#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__)
在这里,我们定义了LOGD和LOGI 可变參数宏,分别相应不同级别的__andoid_log_print函数。这样我们在代码中,就能够直接通过LOGD和LOGI来写入log信息了。
在log.h头文件里,我们能够查到LOG相应的级别信息,例如以下:
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;
3)接下来。就是怎样使用LOGI或者LOGD了。例如以下,在程序中须要写入log的地方,调用函数:
JNIEXPORT void JNICALL Java_com_lms_jni_ParamTransferTest_changeTestVal
(JNIEnv * env, jobject obj){
jclass clazz = (*env)->GetObjectClass(env,obj);
jint val = (*env)->GetStaticIntField(env, clazz,
(*env)->GetStaticFieldID(env, clazz,"testval","I"));
LOGI("before change testval = %d", val);
val = val + 1;
LOGI("after change testval = %d", val);
(*env)->SetStaticIntField(env, clazz,(*env)->GetStaticFieldID(env, clazz,"testval","I"),val);
}
4)到这一步。在C/C++中的使用就结束了,可是JNI的使用一般都是通过编译成共享库的形式,所以我们还须要在Android.mk文件里指定相应的库文件,例如以下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := com_lms_jni_HwDemo
LOCAL_SRC_FILES := \
HwDemo.c \
JniTest.c \
ParamTransferTest.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
当中,我们能够看到 LOCAL_LDLIBS += -llog,在这里。LOCAL_LDLIBS 是告诉编译器,在编译这个共享库的时候,我们要去链接系统库中某一个库。而-llog,事实上就是代表
liblog库的意思,-l是表明lib,而log则是表明前缀是lib的liblog的库。跟LOCAL_MODULE一样。编译器和链接器会自己主动处理前缀lib跟后缀.so,而liblog.so这个库就是在ndk提供的系统库中。例如以下:
5)通过这几步。我们就能够像在Android调试一样,在C/C++中去调试我们的程序了。
结束。
Android中关于JNI 的学习(五)在C文件里使用LogCat的更多相关文章
- Android中关于JNI 的学习(零)简单的样例,简单地入门
Android中JNI的作用,就是让Java可以去调用由C/C++实现的代码,为了实现这个功能.须要用到Anrdoid提供的NDK工具包,在这里不讲怎样配置了,好麻烦,配置了好久. . . 本质上,J ...
- Android中关于JNI 的学习(三)在JNI层訪问Java端对象
前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...
- Android中关于JNI 的学习(四)简单的样例,温故而知新
在第零篇文章简单地介绍了JNI编程的模式之后.后面两三篇文章,我们又针对JNI中的一些概念做了一些简单的介绍,也不知道我究竟说的清楚没有.但相信非常多童鞋跟我一样.在刚開始学习一个东西的时候,入门最好 ...
- Android中关于JNI 的学习(六)JNI中注冊方法的实现
在前面的样例中,我们会发现,当在Java类中定义一个方法的时候,例如以下: public class ParamTransferTest { public static int testval = 1 ...
- Android中关于JNI 的学习(一)对于JNIEnv的一些认识
一个简单的样例让我们初步地了解JNI的作用.可是关于JNI中的一些概念还是需要了解清楚,才干够更好的去利用它来实现我们想要做的事情. 那么C++和Java之间的是怎样通过JNI来进行互相调用的呢? 我 ...
- Android中的SQLite使用学习
Android中的SQLite使用学习 SQLite是非常流行的嵌入式关系型数据库,轻载, 速度快,而且是开源.在Android中,runtime提供SQLite,所以我们可以使用SQLite,而且是 ...
- android中使用jni对字符串加解密实现分析
android中使用jni对字符串加解密实现分析 近期项目有个需求.就是要对用户的敏感信息进行加密处理,比方用户的账户password,手机号等私密信息.在java中,就对字符串的加解密我们能够使用A ...
- 深入理解Android(5)——从MediaScanner分析Android中的JNI
前面几篇介绍了Android中的JNI和基本用法,这一篇我们通过分析Android源代码中的JNI实例,来对JNI部分做一个总结. 一.通向两个不同世界的桥梁 在前面我们说过,JNI就像一个桥梁,将J ...
- 深入理解Android(2)——理解Android中的JNI(中)
阳光小强参加了CSDN博客之星评选,如果你觉得阳光小强的博客对你有所帮助,为小强投上一票吧:http://vote.blog.csdn.net/blogstar2014/details?usernam ...
随机推荐
- IdentityServer4在Asp.Net Core中的应用(三)
今天的内容是授权模式中的简化模式,还是先看以下授权流程图: 在这种模式中我们将与OpenID结合使用,所以首先我们要了解OpenID和OAuth的区别,关于他们的区别,在我上一篇博客<理解Ope ...
- 2-4-搭建DHCP服务实现动态分配IP地址-NTP网络时间同步
本节所讲内容: •DHCP服务器工作原理 •使用DHCP为局域网中的机器分配IP地址 •使用DHCP为服务器分配固定IP地址 •ntpdate加计划任务同步服务器时间 ---------------- ...
- garylog学习篇
官方文档:https://www.graylog.org/ 简介 Graylog 是一个简单易用.功能较全面的日志管理工具,相比 ELK 组合, 优点: 部署维护简单查询语法简单易懂(对比ES的语法… ...
- Neutron之OVS
OVS即开放虚拟交换标准,不仅仅是为了支持OpenFlow协议,而是为了给虚拟化平台上运行的虚拟机实例提供一套纯软件实现的路由交换协议栈.具体点说,Open vSwitch是在开源的Apache2.0 ...
- Android 屏幕密度适配
Android Icon Size and Location for Apps 分辨率 DPI Density scale 1dp对应像素 1dp对应物理尺寸 Location Icon Size ...
- .NET中,在方法参数的类型前加一个OUT是做什么用的
话说古时候,在一个名字叫C#的繁华的大城市里面,有两家珠宝加工店,一家叫ref,另外一家叫out. 有一天,有名字叫a和b的两个人每人都各带了一公斤黄金要加工首饰. a去了ref店,ref的掌柜告诉a ...
- RTP协议学习
RTP协议是承载在UDP协议之上的应用协议 http://blog.csdn.net/chen495810242/article/details/39207305 http://blog.51cto. ...
- libcurl 错误码总结
下载出现这种错误(Requested range was not delivered by the server ),说明是重复下载,删掉本地的再下载就不会出现了
- HTML中Div、span、label标签的区别
div与span 大家在初学div+css布局时,有很多困惑,在div与span的使用过程没觉得有一定的”章法”,觉得两个区别不大,在w3c的关于div和span的定义:div作为分割文档结构自然使它 ...
- libcurl使用认证证书 https认证
在server.xml中增加下面的内容: ciphers="SSL_RSA_WITH_RC4_128_SHA" 下面是libcurl 的测试代码: #include <std ...