These days and leader interview. It feels good. The key is my daughter. Not easy. It's the technical side. It's not easy for me to say that it's not easy to interview, but it's not easy to write code in. Elder brother Hang around so many years, the woman code write very good really not much.
In fact, at any time, as long as an interview feel that they will be less. All this. That can only continue to enhance the ability. Begin to focus on native code learning. Today we talk about the log mechanism, this thing is not easy. Just talk about how log is written to the driver today.
Some people say this is easier, to play Log, in the Java directly log.d log.i LOG.E can be. Well, yes, that's the problem.
1 How does Java write data to a device?
2 How do I play log in the native program?
A road from ancient Huashan, see Code Bar.
public static int d (string tag, string msg) {
Return println_native (Log_id_main, DEBUG, Tag, msg);
}
Do not see do not know, a look startled, originally these data through J//marvell Shun Chunji ni directly written to the device. See how JNI is written.
Static Jint android_util_log_println_native (jnienv* env, Jobject Clazz,
Jint Bufid, Jint priority, Jstring Tagobj, jstring msgobj)
{
Const char* tag = NULL;
Const char* msg = NULL;
if (msgobj = = NULL) {
Jnithrownullpointerexception (env, "println needs a Message");
return-1;
}
if (Bufid < 0 | | Bufid >=//marvell Shun Chunji log_id_max) {
Jnithrownullpointerexception (env, "bad Bufid");
return-1;
}
if (tagobj! = NULL)
Tag = Env->getstringutfchars (Tagobj, NULL);
msg = Env->getstringutfchars (msgobj, NULL);
int res = __android_log_buf_write (Bufid, (android_logpriority) priority, tag, msg);
if (tag! = NULL)
Env->releasestringutfchars (tagobj, tag);
Env->releasestringutfchars (Msgobj, msg);
return res;
}
This is more clear, clear the meaning of the parameters. Which device did the data write to?
Crw-rw-rw-root Log ten, 1970-01-01 16:42 events
CRW-------root log, 1970-01-01 16:42 kernel
Crw-rw-rw-root log, PNs 1970-01-01 16:42 Main
Crw-rw-rw-root Log ten, 1970-01-01 16:42 Radio
Crw-rw-rw-root Log ten, 1970-01-01 16:42 system
What is the priority, what is the tag of the message? What data was written. We didn't see the writing device node here. In any case, JNI acquires the Java layer string through Getstringutfchars.
int __android_log_buf_write (int bu//marvell Shun Chunji fid, int prio, const char *tag, const char *msg)
{
struct Iovec vec[3];
Char tmp_tag[32];
if (!tag)
Tag = "";
/ * Xxx:this needs to go! * /
if ((bufid! = Log_id_radio) &&
(!STRCMP (tag, "Htc_ril") | |
!strncmp (Tag, "RIL", 3) | |/* ANY log tag with "RIL" as the prefix */
!strncmp (Tag, "IMS", 3) | |/* ANY log tag with "IMS" as the prefix */
!strcmp (Tag, "at") | |
!strcmp (Tag, "GSM") | |
!strcmp (Tag, "STK") | |
!strcmp (Tag, "CDMA") | |
//marvell Shun Chunji
!strcmp (Tag, "PHONE") | |
!strcmp (Tag, "SMS"))) {
Bufid = Log_id_radio;
/ * Inform Third party apps/ril/radio: to use Rlog or Rlog * /
snprintf (Tmp_tag, sizeof (Tmp_tag), "use-rlog/rlog-%s", tag);
tag = Tmp_tag;
}
if (Prio = = android_log_fatal) {
Android_set_abort_message (msg);
}
Vec[0].iov_base = (unsigned char *) &prio;
Vec[0].iov_len = 1;
Vec[1].iov_base = (void *) tag;
Vec[1].iov_len = strlen (tag) + 1;
Vec[2].iov_base = (void *) msg;
Vec[2].iov_len = strlen (msg) + 1;
Return Write_to_log (Bufid, VEC, 3);
}
Here we put all the information in the structure array, why should I put it in the structure I array? I don't know yet. The Bufferid and tag are verified here, and the log class writes all the information to the/dev/main device. Here, some tag information is written to the/dev/radio device, which is the modem information
static int __write_to_log_init (log_id_t, struct//marvell Shun Chunji iovec *vec, size_t nr);
static int (*write_to_log) (log_id_t, struct Iovec *vec, size_t nr) = __write_to_log_init;
As you can see here, this is a function pointer,
static int __write_to_log_init (log_id_t log_id, struct Iovec *vec, size_t nr)
{
Pthread_mutex_lock (&log_init_lock);
if (Write_to_log = = __write_to_log_init) {
Log_fds[log_id_main] = Log_open ("/dev/" Logger_log_main, o_wronly);
Log_fds[log_id_radio] = Log_open ("/dev/" Logger_log_radio, o_wronly);
Log_fds[log_id_events] = Log_open ("/dev/" logger_log_events, o_wronly);
Log_fds[log_id_system] = Log_open ("/dev/" Logger_log_system, o_wronly);
Write_to_log = __write_to_log_kernel;
if (Log_fds[log_id_main] < 0 | | Log_fds[log_id_radio] < 0 | |
Log_fds[log_id_events] < 0) {
Log_ Close (Log_fds[log_id_main]);
Log_close (Log_fds[log_id_radio]);
Log_close (log_fds[log_id_events]);
//marvell Shun Chunji
Log_fds[log_id_main] = 1 ;
Log_fds[log_id_radio] =-1;
log_fds[log_id_events] =-1;
Write_to_log = __write_to_log_null;
if (Log_fds[log_id_system] < 0) {
Log_fds[log_id_system] = Log_fds[log_id_main];
}
}
Pthread_mutex_unlock (&log_init_lock);
Return Write_to_log (log_id, VEC, nr);
}
Here Google Play a little trick, Write_to_log = __write_to_log_init, after the initialization changed to Write_to_log = __write_to_log_kernel;
This is the write device node. Thus, the last
int Writev (int fd, const struct iovec* vecs, int count)//cjzang
{
int total = 0;
for (; count > 0; count--, vecs++) {
cons T char* buf = vecs->iov_base;
int len = Vecs->iov_len;
while (len > 0) {
int ret = write (fd , buf, Len); Marvell Shun Chunji
if (Ret < 0) {
if ( Total = = 0)
goto Exit;
if (ret = = 0)
goto Exit;
Total + = ret;
BUF + = ret;
Len-= ret;
}
}
Exit:
return total;
}
In this way, the wave depression was written in. I'm going to write it in. It's written in the driver.
How does the native code add log? How does he sometimes write in it?
Native you need to do a few things to print log,
1 contains the header file, and that's the question, which header file should I include? Android so big, so long files, VIP, waist pain. This header file needs to be included with System/core/include/log/log.h.
#include <log/log.h> also need to define Log_tag in the file
And then we need to add the place
ALOGD ("===========================");
Then you need to add #local_shared_libraries to the makefile: = Liblog
Can, in fact, look inside the realization, is also into the
int __android_log_buf_print (int bufid, int prio, const char *tag, const char *FMT, ...)
{
Va_list ap;
Char Buf[log_buf_size];
Va_start (AP, FMT);
vsnprintf (buf, log_buf_size, FMT, AP);
Va_end (AP);
Return __android_log_buf_write (Bufid, Prio, Tag, buf);
}
In this way, the log information is written in response to the specific I device node.
The whole thing is not good.
Android Log write mechanism