java frame linux_JAVA环境(下) - Android框架简介_Linux编程_Linux公社-Linux系统门户网站...

news/2024/5/20 21:07:37/文章来源:https://blog.csdn.net/weixin_28797919/article/details/115068875

上节讲到了JAVA框架代码和应用程序的关系,那么框架代码和驱动层是怎么联系的呢?这就是这一节的内容:JNI

java使用一种叫做jni的技术来支持对C/C++代码的调用,在anroid中jni的代码放在froyo/frameworks/base/core/jni下,当然在java框架代码的目录下还有其他地方也多多少少放了jni代码,大家可以打开源码来看看。

整体关系如下图:

| java应用程序

--------------------------------------- Android系统api

| java框架

|本地接口声明

--------------------------------------

| JNI

--------------------------------------

| C/C++代码

继续拿来主义,C/C++中调试用printf,内核调试用printk,呵呵,android调试用log,那么我们就分析log的实现。

log的java代码froyo/frameworks/base/core/java/android/util/Log.java,

/*

* Copyright (C) 2006 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

packageandroid.util;

importcom.android.internal.os.RuntimeInit;

importjava.io.PrintWriter;

importjava.io.StringWriter;

/**

* API for sending log output.

*

Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()

* methods.

*

The order in terms of verbosity, from least to most is

* ERROR, WARN, INFO, DEBUG, VERBOSE.  Verbose should never be compiled

* into an application except during development.  Debug logs are compiled

* in but stripped at runtime.  Error, warning and info logs are always kept.

*

Tip: A good convention is to declare a TAG constant

* in your class:

*

private static final String TAG = "MyActivity";

*

* and use that in subsequent calls to the log methods.

*

Tip: Don't forget that when you make a call like

Log.v(TAG, "index=" + i);

* that when you're building the string to pass into Log.d, the compiler uses a

* StringBuilder and at least three allocations occur: the StringBuilder

* itself, the buffer, and the String object.  Realistically, there is also

* another buffer allocation and copy, and even more pressure on the gc.

* That means that if your log message is filtered out, you might be doing

* significant work and incurring significant overhead.

*/

publicfinalclassLog {

/**

* Priority constant for the println method; use Log.v.

*/

publicstaticfinalintVERBOSE =2;

/**

* Priority constant for the println method; use Log.d.

*/

publicstaticfinalintDEBUG =3;

/**

* Priority constant for the println method; use Log.i.

*/

publicstaticfinalintINFO =4;

/**

* Priority constant for the println method; use Log.w.

*/

publicstaticfinalintWARN =5;

/**

* Priority constant for the println method; use Log.e.

*/

publicstaticfinalintERROR =6;

/**

* Priority constant for the println method.

*/

publicstaticfinalintASSERT =7;

/**

* Exception class used to capture a stack trace in {@link #wtf()}.

*/

privatestaticclassTerribleFailureextendsException {

TerribleFailure(String msg, Throwable cause) {super(msg, cause); }

}

privateLog() {

}

/**

* Send a {@link #VERBOSE} log message.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

*/

publicstaticintv(String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, VERBOSE, tag, msg);

}

/**

* Send a {@link #VERBOSE} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @param tr An exception to log

*/

publicstaticintv(String tag, String msg, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, VERBOSE, tag, msg +'/n'+ getStackTraceString(tr));

}

/**

* Send a {@link #DEBUG} log message.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

*/

publicstaticintd(String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, DEBUG, tag, msg);

}

/**

* Send a {@link #DEBUG} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @param tr An exception to log

*/

publicstaticintd(String tag, String msg, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, DEBUG, tag, msg +'/n'+ getStackTraceString(tr));

}

/**

* Send an {@link #INFO} log message.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

*/

publicstaticinti(String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, INFO, tag, msg);

}

/**

* Send a {@link #INFO} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @param tr An exception to log

*/

publicstaticinti(String tag, String msg, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, INFO, tag, msg +'/n'+ getStackTraceString(tr));

}

/**

* Send a {@link #WARN} log message.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

*/

publicstaticintw(String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, WARN, tag, msg);

}

/**

* Send a {@link #WARN} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @param tr An exception to log

*/

publicstaticintw(String tag, String msg, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, WARN, tag, msg +'/n'+ getStackTraceString(tr));

}

/**

* Checks to see whether or not a log for the specified tag is loggable at the specified level.

*

*  The default level of any tag is set to INFO. This means that any level above and including

*  INFO will be logged. Before you make any calls to a logging method you should check to see

*  if your tag should be logged. You can change the default level by setting a system property:

*      'setprop log.tag. '

*  Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will

*  turn off all logging for your tag. You can also create a local.prop file that with the

*  following in it:

*      'log.tag.='

*  and place that in /data/local.prop.

*

* @param tag The tag to check.

* @param level The level to check.

* @return Whether or not that this is allowed to be logged.

* @throws IllegalArgumentException is thrown if the tag.length() > 23.

*/

publicstaticnativebooleanisLoggable(String tag,intlevel);

/*

* Send a {@link #WARN} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param tr An exception to log

*/

publicstaticintw(String tag, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));

}

/**

* Send an {@link #ERROR} log message.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

*/

publicstaticinte(String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, ERROR, tag, msg);

}

/**

* Send a {@link #ERROR} log message and log the exception.

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @param tr An exception to log

*/

publicstaticinte(String tag, String msg, Throwable tr) {

returnprintln_native(LOG_ID_MAIN, ERROR, tag, msg +'/n'+ getStackTraceString(tr));

}

/**

* What a Terrible Failure: Report a condition that should never happen.

* The error will always be logged at level ASSERT with the call stack.

* Depending on system configuration, a report may be added to the

* {@link android.os.DropBoxManager} and/or the process may be terminated

* immediately with an error dialog.

* @param tag Used to identify the source of a log message.

* @param msg The message you would like logged.

*/

publicstaticintwtf(String tag, String msg) {

returnwtf(tag, msg,null);

}

/**

* What a Terrible Failure: Report an exception that should never happen.

* Similar to {@link #wtf(String, String)}, with an exception to log.

* @param tag Used to identify the source of a log message.

* @param tr An exception to log.

*/

publicstaticintwtf(String tag, Throwable tr) {

returnwtf(tag, tr.getMessage(), tr);

}

/**

* What a Terrible Failure: Report an exception that should never happen.

* Similar to {@link #wtf(String, Throwable)}, with a message as well.

* @param tag Used to identify the source of a log message.

* @param msg The message you would like logged.

* @param tr An exception to log.  May be null.

*/

publicstaticintwtf(String tag, String msg, Throwable tr) {

tr =newTerribleFailure(msg, tr);

intbytes = println_native(LOG_ID_MAIN, ASSERT, tag, getStackTraceString(tr));

RuntimeInit.wtf(tag, tr);

returnbytes;

}

/**

* Handy function to get a loggable stack trace from a Throwable

* @param tr An exception to log

*/

publicstaticString getStackTraceString(Throwable tr) {

if(tr ==null) {

return"";

}

StringWriter sw =newStringWriter();

PrintWriter pw =newPrintWriter(sw);

tr.printStackTrace(pw);

returnsw.toString();

}

/**

* Low-level logging call.

* @param priority The priority/type of this log message

* @param tag Used to identify the source of a log message.  It usually identifies

*        the class or activity where the log call occurs.

* @param msg The message you would like logged.

* @return The number of bytes written.

*/

publicstaticintprintln(intpriority, String tag, String msg) {

returnprintln_native(LOG_ID_MAIN, priority, tag, msg);

}

/** @hide */publicstaticfinalintLOG_ID_MAIN =0;

/** @hide */publicstaticfinalintLOG_ID_RADIO =1;

/** @hide */publicstaticfinalintLOG_ID_EVENTS =2;

/** @hide */publicstaticfinalintLOG_ID_SYSTEM =3;

/** @hide */publicstaticnativeintprintln_native(intbufID,

intpriority, String tag, String msg);

}

我们看到所有代码都是调用public static native int println_native(int bufID,

int priority, String tag, String msg);来实现输出的,这个函数的实现就是C++,调用的方式就是JNI

我们看一下对应的jni代码froyo/frameworks/base/core/jni/android_util_Log.cpp,最终调用的输出函数是

/*

* In class android.util.Log:

*  public static native int println_native(int buffer, int priority, String tag, String msg)

*/

staticjint android_util_Log_println_native(JNIEnv* env, jobject clazz,

jint bufID, jint priority, jstring tagObj, jstring msgObj)

{

constchar* tag = NULL;

constchar* msg = NULL;

if(msgObj == NULL) {

jclass npeClazz;

npeClazz = env->FindClass("java/lang/NullPointerException");

assert(npeClazz != NULL);

env->ThrowNew(npeClazz,"println needs a message");

return-1;

}

if(bufID <0|| bufID >= LOG_ID_MAX) {

jclass npeClazz;

npeClazz = env->FindClass("java/lang/NullPointerException");

assert(npeClazz != NULL);

env->ThrowNew(npeClazz,"bad bufID");

return-1;

}

if(tagObj != NULL)

tag = env->GetStringUTFChars(tagObj, NULL);

msg = env->GetStringUTFChars(msgObj, NULL);

intres = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);

if(tag != NULL)

env->ReleaseStringUTFChars(tagObj, tag);

env->ReleaseStringUTFChars(msgObj, msg);

returnres;

}

当然我们发现最终输出是

intres = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);

用力grep了一下代码,结果如下

./system/core/include/cutils/log.h:int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);

./system/core/liblog/logd_write.c:int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)

./system/core/liblog/logd_write.c:    return __android_log_buf_write(bufID, prio, tag, buf);

这个就是和android专用驱动进行通信的方式,这个分析下去就有点深了,后面分析。

以上三个小节分析了android的JAVA环境,我这里都是简单的抛砖引玉,希望能给大家一点大体的指引,其他修行靠大家了,能成为是一个android程序员是多么幸福的事情,各位已经在幸福中了,我什么时候也可以幸福一把??0b1331709591d260c1c78e86d0c51c18.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_711932.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无SSH工具部署网站到火腿云

无SSH工具, 部署成品网站到火腿云服务器 文章目录无SSH工具, 部署成品网站到火腿云服务器前言一、准备工作二、部署流程总结前言 画了9块买了个火腿云服务器来部署我的项目,但是网上几乎查不到火腿云的教程,而且其他教程大多是自建服务器部署网站的教程,看起来体验也不是很好,…

全流程 部署Vue+Node网站到阿里云

文章目录前言一、搞到一个使用权二、远程连接SSH工具远程连接VNC远程连接三、安装可视化面板四、进入可视化面板面板收尾工作五、部署网站部署前端文档部署后端文档导入数据库六、常见翻车解决方法总结前言 白嫖的服务器到期了… 被迫再做一次, 也好, 上次摸摸索索的, 也没正儿…

php vue seo,处理 Vue 单页面 SEO 的另一种思路

(设置vue 单页面meta info信息&#xff0c;如果需要单页面SEO&#xff0c;可以和 prerender-spa-plugin形成更优的配合)单页面应用在前端正大放光彩。三大框架 Angular、Vue、React&#xff0c;可谓妇孺皆知。随着单页面应用的普及&#xff0c;人们在感受其带来的完美的用户体验…

宝塔如何备份网站_宝塔备份网站怎样还原_服务器备份数据恢复教程

之前介绍了“宝塔面板自动备份网站和数据库到FTP存储空间教程”&#xff0c;那么宝塔备份的网站数据怎么恢复呢&#xff1f;所以本文来教大家怎么把网站从备份数据还原。宝塔备份的数据在什么地方&#xff1f;宝塔面板后台可以自动或者手动给网站数据备份&#xff0c;备份后数据…

php教育网站设计案例_南广东区优秀网站设计案例集锦第四期

南广东优秀网站设计案例集锦第四期第一名&#xff1a;吴嘉文佛山资深设计师01个人介绍亚里士多德曾经说过&#xff1a;“我们每一个人都是由自己一再重复的行为所铸造的。因而优秀不是一种行为&#xff0c;而是一种习惯。”嘉文是2010年加入中企至今&#xff0c;至今从事网站设…

计算机专业论文选题网站方面,5大网站汇总,搞定新颖的计算机专业毕业设计网站汇总...

原标题&#xff1a;5大网站汇总&#xff0c;搞定新颖的计算机专业毕业设计网站汇总2021年了&#xff0c;很多计算机专业的同学都会问&#xff0c;我不想再做XX管理系统、XX选课系统了&#xff0c;哪里有一些新颖的毕业设计题目可以参考&#xff1f;或者做新颖的毕业设计应该浏览…

让自己的网站变成暗黑模式

让自己的网站变成暗黑模式只需要一行简简单单的CSS代码就可以完成啦&#xff1a;html[themedark-mode] {filter: invert(1) hue-rotate(180deg); }来看看最终的效果如何&#xff1a;从图中我们可以看得&#xff0c;网站的整个背景都变成了黑色的&#xff0c;字体变成了白色的。…

小米集团王嵋因错误表达致歉并请辞;亚马逊云服务出现中断,许多网站受到影响;deepin 深度系统更新发布|极客头条...

整理 | 郑丽媛头图 | CSDN 下载自东方 IC快来收听极客头条音频版吧&#xff0c;智能播报由出门问问「魔音工坊」提供技术支持。「极客头条」—— 技术人员的新闻圈&#xff01;CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技…

php 加载慢,PHP版网站缓存加快打开速度的方法分享

说明&#xff1a;1&#xff0c;在服务器缓存了压缩过的文件&#xff0c;再次访问减少再压缩时间&#xff0c;降低CPU占用率。2&#xff0c;通过设置客户端文件缓存时间&#xff0c;降低再次请求次数&#xff0c;可降低85%以上。3&#xff0c;图片因为已经是压缩格式&#xff0c…

php网站模板怎么修改,自己做网站如何用好并自主修改网上的免费模板

用过PHP开源程序的人都知道&#xff0c;采用wordpress程序&#xff0c;上传到空间后&#xff0c;每个人的网站都是一样的&#xff0c;一个默认的版面。这是本人比较不喜欢的版面&#xff0c;一张老到掉牙的图片永远呆在网站顶部&#xff0c;黑白搭配的主色调也实在让人难以恭维…

怎么在服务器添加充值网站,云服务器怎么弄充值

云服务器怎么弄充值 内容精选换一换华为云帮助中心&#xff0c;为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档&#xff0c;帮助您快速上手使用华为云服务。用户的弹性云服务器已绑定EIP&#xff0c;但是无法连接到Inter…

token会被截取吗_做抖音搬运其他网站视频可以吗?

HI,亲爱的朋友你好&#xff0c;我是陈奶爸&#xff0c;专注于短视频营销与创收&#xff01;最近有不少朋友问&#xff0c;可不可以从其他视频网站搬运作品到抖音呢&#xff1f;这个问题是要分情况对待&#xff1a;第一种&#xff1a;直接下载与上传&#xff01;比如从快手上下载…

使用 filter 置灰网站需要注意!

最近在做一个置灰网站的需求&#xff0c;我跟大部分网站一样使用了 CSS 的 filter 滤镜功能&#xff0c;但是事情并没有原本的那么简单&#xff0c;如果使用不当&#xff0c;还会引发线上事故。位置问题代码如下&#xff1a;<!DOCTYPE html> <html lang"en"…

腾讯回应 PC 微信扫描浏览器 cookies;约会网站 228 万用户数据泄露;Java 1.0 发布 25周年 | 极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01;CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。整理 | 丁恩华出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;快来收听极客头条音频版吧&a…

编程网站 Perl.com 被劫,售价 19 万美元

整理 | 郑丽媛 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 1987 年诞生的 Perl&#xff0c;尽管近年来不如 Python 和 Rust 这类年轻的编程语言时常活跃在大众视野&#xff0c;但 33 年后的如今依旧排在 TIOBE 榜前二十&#xff0c;Perl 必定有其不可取代的优…

CTO 写的低级 Bug 再致网站被黑,CEO 的号都被盗了!

整理 | 郑丽媛出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;上周&#xff0c;美国开源社交网络服务平台 Gab &#xff0c;因其 CTO 写的低级 Bug 受到黑客攻击&#xff0c;导致约 70GB 的数据被窃取。可该公司开发者还没完全修复其易受攻击的代码&#xff0c;本周…

wordpress如何让百度快速收录_如何让百度收录网站?

百度是我国国内主流搜索引擎之一&#xff0c;对于网站的收录制定了一系列的规则&#xff0c;对于新站收录尤为严格&#xff0c;要想让百度收录网站的话&#xff0c;应该从关键词布局、网站推广渠道、用户体验、内容和链接等多个细节方面着手做好优化&#xff0c;这样才能增加百…

入侵sf服务器技术_入侵服务器、疯狂攻击各种网站, 这个黑客团伙终被“团灭”!...

8月9日&#xff0c;记者从汉川市网安大队获悉&#xff0c;汉川警方在省、市网安部门的大力支持下&#xff0c;利用大数据技术&#xff0c;强化网络犯罪的发现机制&#xff0c;深度研判分析&#xff0c;全面掌握隐藏在网络背后的犯罪链条&#xff0c;成功打掉一个黑客团伙&#…

php7.1 集成php fpm,LNMP建站教程(2):安装 PHP 7.1 与 PHP7.1-FPM以及与Nginx集成

Nginx 和 PHP 是两个独立的程序&#xff0c;它们之间在正常的情况系是没有任何关系的&#xff0c;但是我们又希望 Nginx 在收到 PHP 的动态请求时&#xff0c;可以将请求发送到 PHP的解析器并将结果返回给用户的浏览器。那么就需要有一个通用的交互协议来处理它们间的交互流程&…

beautifulsoup_如何使用 Python 和 BeautifulSoup 爬取网站

作者丨Justin Yek译者丨平川互联网上的信息如此之多&#xff0c;任何人穷其一生也无法全部消化吸收。你需要的不是访问这些信息&#xff0c;而是一种可伸缩的方式&#xff0c;可以用来收集、组织和分析这些信息。你需要的是 Web 爬取。Web 爬取可以自动提取数据&#xff0c;并以…