2016年3月9日星期三
2016年1月12日星期二
iTerm2 快捷键
进入Preferences,Keys,left option改为+Esc
修改option+left:action改为Send Escape Sequence,Esc+为B
修改opton+right:action改为Send Escape Sequence,Esc+为F
增加cmd+left:action改为Send Escape Sequence,Esc+为[H
增加cmd+right:action改为Send Escape Sequence,Esc+为[F
这样option+left、right就是左右移动单词,cmd+left、right就是移动到行首行尾
转自:
2015年2月12日星期四
git中清除的没有引用的对象
鉴于天朝奇葩的网络状态,用repo来下载Android的源代码是一件很痛苦的事,经常会发生网络中断的现象。而不知道是repo还是git的问题,会导致git库重新下载,并且以前下载的部分仍然会保存在文件系统中(我就是眼睁睁地看着Android的代码在中断几次后,从30多G膨胀到50多G,还没有下载完╮(╯﹏╰)╭)。
那么如何解决这个问题呢?我检查了.repo目录,发现在XXX.git/objects/pack下有很多tmp_pack_xxx的文件。这就是下载的临时文件。可以用下面的方法来删除:
repo forall -c “git prune"
2013年6月10日星期一
联想Y500安装Unbuntu12.04
新买了一台联想Y500,预装了Windows8。为了安装Unbuntu和Windows8双系统,折腾了一天。
安装步骤:
1. 分区
Y500预装的Windows8有个盘,C盘和D盘。从D盘划分出部分空间给Ubuntu
1)win键+x,弹出菜单中选择“磁盘管理”
2)选择D盘,右键点击弹出的菜单中选择“压缩卷”
3)输入要划分的空间。
2. 制作LiveUSB安装U盘
1)从ubuntu官网下载Ubuntu12.04.2的iso镜像文件,这个版本开始支持UEFI和SecureBoot。但我后来还是把SecureBoot关掉了(原因见下面第6点)。
2)从另一台Ubuntu机器通过“启动盘创建器”,创建启动U盘。
3)修改U盘下/boot/grub/grub.cfg文件:
"gfxmode=auto"改为"gfxmode=1920*1080"(改成其他分辨率应该也可以,但我没有试验)
所有的"quiet splash"改为"nomodeset=1"。
如果不修改,无法进入grub菜单的选项。
3. 安装Ubuntu
修改BIOS从usb启动,安装Ubuntu。安装选项我选择的是“Install Ubuntu alongside them”。
安装时就可以配置网络,最好是把网络配置好。否则安装完后要在命令行下配置网络又是件头疼的事。
4. 修改新安装的Ubuntu的grub.cfg文件
1) 安装完再次通过usb启动,选择"try Ubuntu"
2) 执行以下命令mount新安装的Ubuntu分区
sudo mkdir /mnt/newinstall
sudo mount /dev/sda8 /mnt/newinstall (sda8是我机器上Ubuntu的分区)
3) sudo vi /mnt/newinstall/boot/grub/grub.conf,修改上面2.3)的选项
5. 安装GT750M显卡驱动
现在可以启动Ubuntu了。但因为没有显卡驱动,启动Ubuntu只能进入shell。驱动可以从Nvidia官网下载。现在最新版的下载地址是
http://us.download.nvidia.com/XFree86/Linux-x86_64/319.23/NVIDIA-Linux-x86_64-319.23.run
执行以下命令:
wget http://us.download.nvidia.com/XFree86/Linux-x86_64/319.23/NVIDIA-Linux-x86_64-319.23.run
sudo chmod +x NVIDIA-Linux-x86_64-319.23.run
sudo ./NVIDIA-Linux-x86_64-319.23.run
驱动安装完成后,再次启动就可以进入图形界面。
6. boot-repair修复Windows8
从Dash或terminal启动boot-repair,选择"Recommended repair",然后按照指示操作即可。
注意:boot-repair会要求关闭SecureBoot,虽然12.04.2(*参考1)支持SecureBoot,但为了安全起见,我还是把SecureBoot关闭了。
7. 选择正确的grub选项启动Windows8
boot-repair修复之后grub会生成很多选项,包括联想的一键恢复(下面第3个选项)都会显示出来。
下面列举几个我机器上的grub选项:
Ubuntu, Linux 3.5.0-32-generic
Windows Boot UEFI recovery
Windows Boot UEFI recovery bkpbootx64.efi
Windows 8 (loader) (on /dev/sda5)
这里就有个很坑爹的问题。启动Windows8不是选第4个!导致我以为boot-repair没有成功,重试了好几次。万般无奈之下,我无聊地一个个去试,发现第2个"Windows Boot UEFI recovery"居然进去了。。。
原来此recovery(boot-repair之后成功修复的recovey)非彼recovery(恢复模式),我一直理解成类似Android的recovery模式了orz
好了,终于双系统都可以正常启动了。
参考
1. https://help.ubuntu.com/community/UEFI
2. http://askubuntu.com/questions/272570/unable-to-install-ubuntu-on-lenovo-y500
3. http://askubuntu.com/questions/221835/installing-ubuntu-on-a-pre-installed-uefi-supported-windows-8-system
2012年10月29日星期一
backtrace显示调用栈层次
代码摘自man backtrace
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void
myfunc3(void)
{
int j, nptrs;
#define SIZE 100
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
static void /* "static" means don't export the symbol... */
myfunc2(void)
{
myfunc3();
}
static void /* "static" means don't export the symbol... */
myfunc2(void)
{
myfunc3();
}
void
myfunc(int ncalls)
{
if (ncalls > 1)
myfunc(ncalls - 1);
else
myfunc2();
}
int
main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "%s num-calls\n", argv[0]);
exit(EXIT_FAILURE);
}
myfunc(atoi(argv[1]));
exit(EXIT_SUCCESS);
}
2012年7月8日星期日
电话相关缩略语
AAA
Authentication, Authorization and Accounting 认证 授权和计费
AN-AAA
Access Network AAA 接入网络认证的AAA
AT
Access Terminal 接入终端
CAVE
Cellular Authentication and Voice Encryption algorithm 蜂窝鉴权和语音加密算法
CHAP
Challenge Handshake Authentication Protocol 查询握手认证协议
IMSI
International Mobile Subscriber Identity 国际移动用户识别码
IOS
Inter-Operability Specification 互操作规范
MEI
Mobility Event Indicator 移动性事件指示
MS
Mobility Station 移动台,本文指双模手机
SIP
Session Initiation Protocol 会话初始化协议
UDP
User Datagram Protocol 用户数据报协议
UIM
User Identity Model 用户识别模块
WAG
WLAN Access Gateway WLAN 接入网关
WLAN
Wireless Local Area Network 无线局域网
wPDIF
WiFi Packet Data Interworking Function WiFi 分组数据互联网关
2012年7月5日星期四
2012年5月6日星期日
admob代码一例
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
AdView adView = new AdView(GAEProxy.this, AdSize.BANNER, "a14d8be8a284afc");
FrameLayout layout = (FrameLayout) findViewById(R.id.ad);
layout.addView(adView);
AdRequest aq = new AdRequest();
adView.loadAd(aq);
......
adView.destroy(); //结束时销毁
2012年3月27日星期二
【转】手机制式的解释
Preferred Network Types change the type of frequency the phone searches for.
Android is used on several devices that can gain access to different cell carriers. The 'Testing' menu that contains the 'preferred network types' you are referring you to is used for all of those Android devices as far as I can tell.
For simplicity, there are two main types of cell carriers, GSM and CDMA.
The following popular data communication technology is associated with each cell carrier type:
GSM = GPRS (2g), EDGE(2g), UMTS(3g), WCDMA(3g), HSDPA(3g) {Cell Carrier examples: AT&T and T-Mobile}
CDMA = CDMA*(2/3g) EV-DO(3g) WiMax(3/4g) {Cell Carrier examples: Verizon and Sprint}
Now that the general stuff is out of the way, here's my take on the Preferred Network types:
WCDMA preferred - The GSM phone is capable of using both 2G and 3G data communication and when signal strength is low 3G is favored more.
GSM only - The GSM phone is capable of using only 2G data communication. When the 2G signal is too low you get nothing at all.
WCDMA only - The GSM phone is capable of using only 3G data communication. When the 3G signal is too low you get nothing at all.
GSM auto (PRL) - The GSM phone is capable of using both 2G and 3G data communication and when signal strength is low 2G is favored more. This one is a bit confusing to me since PRL is associated mostly with CDMA technology and not GSM technology.
CDMA auto (PRL) - The CDMA phone is capable of using both 2G and 3G data communication and when signal strength is low 2G is favored more.
CDMA only - The CDMA phone is capable of using only 2G data communication. When the 2G signal is too low you get nothing at all.
EvDo only - The CDMA phone is capable of using only 3G data communication. When the 3G signal is too low you get nothing at all.
GSM/CDMA auto (PRL) - Some phones are equipped with both GSM and CDMA capabilities. This setting appears to just have the phone attempt to stay connected to the data communication type that works the best. (Maybe the Samsung Galaxy S will take advantage of this???)
Unknown - If none of the above fit or the phone is acting weird as far as connecting to the carrier, you will see your preferred network type is set to this
When using the 'only' options you should still be able to make calls.
To put things into perspective, The Nexus One is set to WCDMA preferred as default and the Droid Incredible is set to CDMA auto (PRL).
Some References:
http://www.google.com/support/forum/p/android/thread?tid=34f1f0c3bc7affe1&hl=en
http://en.wikipedia.org/wiki/3G
http://en.wikipedia.org/wiki/Preferred_Roaming_List
http://ncare.com/2010/03/29/how-to-update-your-phones-with-the-newest-towers/
Android is used on several devices that can gain access to different cell carriers. The 'Testing' menu that contains the 'preferred network types' you are referring you to is used for all of those Android devices as far as I can tell.
For simplicity, there are two main types of cell carriers, GSM and CDMA.
The following popular data communication technology is associated with each cell carrier type:
GSM = GPRS (2g), EDGE(2g), UMTS(3g), WCDMA(3g), HSDPA(3g) {Cell Carrier examples: AT&T and T-Mobile}
CDMA = CDMA*(2/3g) EV-DO(3g) WiMax(3/4g) {Cell Carrier examples: Verizon and Sprint}
Now that the general stuff is out of the way, here's my take on the Preferred Network types:
WCDMA preferred - The GSM phone is capable of using both 2G and 3G data communication and when signal strength is low 3G is favored more.
GSM only - The GSM phone is capable of using only 2G data communication. When the 2G signal is too low you get nothing at all.
WCDMA only - The GSM phone is capable of using only 3G data communication. When the 3G signal is too low you get nothing at all.
GSM auto (PRL) - The GSM phone is capable of using both 2G and 3G data communication and when signal strength is low 2G is favored more. This one is a bit confusing to me since PRL is associated mostly with CDMA technology and not GSM technology.
CDMA auto (PRL) - The CDMA phone is capable of using both 2G and 3G data communication and when signal strength is low 2G is favored more.
CDMA only - The CDMA phone is capable of using only 2G data communication. When the 2G signal is too low you get nothing at all.
EvDo only - The CDMA phone is capable of using only 3G data communication. When the 3G signal is too low you get nothing at all.
GSM/CDMA auto (PRL) - Some phones are equipped with both GSM and CDMA capabilities. This setting appears to just have the phone attempt to stay connected to the data communication type that works the best. (Maybe the Samsung Galaxy S will take advantage of this???)
Unknown - If none of the above fit or the phone is acting weird as far as connecting to the carrier, you will see your preferred network type is set to this
When using the 'only' options you should still be able to make calls.
To put things into perspective, The Nexus One is set to WCDMA preferred as default and the Droid Incredible is set to CDMA auto (PRL).
Some References:
http://www.google.com/support/forum/p/android/thread?tid=34f1f0c3bc7affe1&hl=en
http://en.wikipedia.org/wiki/3G
http://en.wikipedia.org/wiki/Preferred_Roaming_List
http://ncare.com/2010/03/29/how-to-update-your-phones-with-the-newest-towers/
2012年3月19日星期一
ERROR: In XXX, unable to find attribute yyy
Android 中定义declare-styleable时碰到这个错误,折腾了3个小时,才发现是<attr>这个tag只写了name,而没有写format。。。
正确的写法是
<attr name="some name" format="string" />
2012年3月14日星期三
[转]如何忽略Android资源编译错误 Error: this attribute must be localized.
http://blog.csdn.net/forlong401/article/details/7218204
这个错误是由于强制要求应用程序按照多国语言的模式开发,避免死的字符串。
但有的时候你发现导入别人的代码,改这些字符串太麻烦,那么可以在Android.mk中添加
LOCAL_MODULE_TAGS := tests
2012年2月15日星期三
调用注释有@hide的方法编译出错
编译Android时,如果Android.mk中有LOCAL_SDK_VERSION,调用注释有@hide的方法会导致编译通不过,
必须把LOCAL_SDK_VERSION去掉。原因不明 �
2012年2月10日星期五
64位linux下安装Beyond Compare
==========================================================
I just got Beyond Compare 3.0.2 for Linux to run on 64-bit Kubuntu 8.04.1. It is pretty painful to setup.Here are the steps:
1. Install 32-bit compatibility library.
Using the graphical package manager, install the package "ia32-libs". You can also install from a terminal using the command "sudo apt-get install ia32-libs".
2. Install 32-bit version of QT3.
(On older versions of Kubuntu/Ubuntu, you may be able to install the
package "ia32-libs-kde", this package isn't available for Kubuntu 8.04.1 AMD64)
Download the 32-bit .deb package for QT3 from http://packages.ubuntu.com/hardy/i38...t3-mt/download.
Extract the contents of the .deb package.
dpkg-deb --extract libqt3-mt_3.3.8-b-0ubuntu3_i386.deb libqt3-mt
Copy the QT3 libraries to Kubuntu's folder for 32-bit libraries.
sudo cp -R libqt3-mt/usr/lib/* /usr/lib32
3. Install Beyond Compare 3 for Linux deb package.
sudo dpkg -i --force-architecture BCompareLinux_080814.deb
4. Run Beyond Compare by typing "bcompare" in a terminal.
2011年12月10日星期六
一直以来,我都以为UTF-16和UCS-2是一样的 囧。
UCS-2: 固定双字节表示一个字符,只能表示 UCS 的子集 BMP。
(UCS-2 扩充后成为 UTF-16,这里我们依然将 UCS-2 指代扩充前的编码方式)
UCS-4: 固定四字节表示一个字符,能表示整个 UCS。
UTF-16: 双字节或者四字节表示一个字符,能表示整个 UCS。
UCS-2 跟 UTF-16 在 BMP 范围兼容。 UCS-2 是废弃的。
UTF-8: 一种编码方式,一到四个字节(*)表示一个字符,能表示整个 UCS。
UTF-32: 同 UCS-4。
(UCS-2 扩充后成为 UTF-16,这里我们依然将 UCS-2 指代扩充前的编码方式)
UCS-4: 固定四字节表示一个字符,能表示整个 UCS。
UTF-16: 双字节或者四字节表示一个字符,能表示整个 UCS。
UCS-2 跟 UTF-16 在 BMP 范围兼容。 UCS-2 是废弃的。
UTF-8: 一种编码方式,一到四个字节(*)表示一个字符,能表示整个 UCS。
UTF-32: 同 UCS-4。
*现在的 Unicode 标准只有 21 位 0 ~ 0x10FFFF
2011年12月9日星期五
使用javamail生成带附件的html邮件
一般来说,带附件并且有图片的html的mime邮件形如以下的格式:
multipart/mixed
multipart/related
multipart/alternative
但JavaMail的FAQ没有详细解释如何发送这种多重嵌套multipart的mime邮件。关键是设置content-type为"message/rfc822",见下面示例代码的黑体部分。
public void createMail() {
......
//这里只示例生成Multipart的代码,其他代码请参考JavaMail的相关文档
Multipart mmp = null;
mmp = getHtmlPart(plaintext, html);
mmp = getRelatedPart(mmp, image);
mmp = getMixedPart(mmp, attachment);
......
}
private Multipart getHtmlPart(String plaintext, String html) throws MessagingException {
MimeMultipart mmp_alt = new MimeMultipart("alternative");
MimeBodyPart mbp_text = new MimeBodyPart();
mbp_text.setContent(plaintext, "text/plain;charset=UTF-8");
mmp_alt.addBodyPart(mbp_text);
MimeBodyPart mbp_html = new MimeBodyPart();
mbp_html.setContent(html, "text/html;charset=UTF-8");
mmp_alt.addBodyPart(mbp_html);
return mmp_alt;
}
private Multipart getRelatedPart(Multipart aPart, String imagesPath) throws MessagingException, UnsupportedEncodingException {
MimeMultipart mmp = new MimeMultipart("related");
MimeBodyPart mbp = new MimeBodyPart();
mbp.setContent(aPart, "message/rfc822");
mmp.addBodyPart(mbp);
String[] imageFiles = imagesPath.split(",");
if (imageFiles.length != 0) {
for (String file : imageFiles) {
MimeBodyPart mbp_file = new MimeBodyPart();
FileDataSource fds = new FileDataSource(file);
mbp_file.setDataHandler(new DataHandler(fds));
mbp_file.setFileName(MimeUtility.encodeText(fds.getName(), "gbk", "B"));
File f = new File(file);
mbp_file.setContentID("<" + f.getName() + ">");
mmp.addBodyPart(mbp_file);
}
}
return mmp;
}
private Multipart getMixedPart(Multipart aPart, String attachPath) throws MessagingException, IOException {
MimeMultipart mmp = new MimeMultipart("mixed");
MimeBodyPart mbp = new MimeBodyPart();
mbp.setContent(aPart, "message/rfc822");
mmp.addBodyPart(mbp);
String[] files = attachPath.split(",");
if (files.length != 0) {
for (String file : files) {
MimeBodyPart mbp_file = new MimeBodyPart();
mbp_file.attachFile(file);
mbp_file.setHeader("Content-Transfer-Encoding", "base64");
mmp.addBodyPart(mbp_file);
}
}
return mmp;
}
salt解释
以前翻阅文档是总会遇上salt这个词,但一直没有理解,今天看到这篇文章,才明白是怎么回事。
salt是一串随机(但是对每个用户是固定的,比如用户名、用户id等)的字符串,附加到密码上生成心得字符串,再用这个字符串生成md5,保存到数据库中。
使用salt和单纯的密码md5比较,有2个好处:
1. 增加破解的难度。数据库在被hack的情况下,如果不知道salt的生成规律,是无法简单地通过字典来暴力破解。
2. 增加破解的时间。即使知道salt生成规律,通过字典暴力破解也只能每次破解一个用户的密码,因为每个用户的salt是不一样的,最终生成的md5也不相同。
而如果只简单保存密码的md5,那么不同用户密码相同的时候,可以通过一次sql查询就破解。
顺便吐槽下,salt其实并不难理解,但是在看定义和用途的解释却让人很难理解。说的通俗点,密码是第一把保险锁,而salt则是网站提供的第二把保险锁。
2011年11月1日星期二
关于动态装载dex
Dalvik目前的实现中,每一个dex文件里最多只能有65536个方法引用。为了解决这个问题,有一种办法是把一个dex分成多个dex,其中一个dex作为APK的主dex,而其他的dex保存在assets中,通过DexClassLoader动态装载进来。
但我实际测试下来,发现并不实用。通过DexClassLoader装载后,每个类必须使用DexClassLoader.loadClass()取到后才能实例化。而代码中有很多使用new实例化的对象,这些类是系统的PathClassLoader来装载,仍然会抛出ClassNotFound异常。而系统的ClassLoader是无法被替换的。
所以看来只好等Google的Dalvik的更新了。
tip:
1. Android的ClassLoader一般是PathClassLoader,PathClassLoader的父classloader是BootClassLoader.
2. when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).
但我实际测试下来,发现并不实用。通过DexClassLoader装载后,每个类必须使用DexClassLoader.loadClass()取到后才能实例化。而代码中有很多使用new实例化的对象,这些类是系统的PathClassLoader来装载,仍然会抛出ClassNotFound异常。而系统的ClassLoader是无法被替换的。
所以看来只好等Google的Dalvik的更新了。
tip:
1. Android的ClassLoader一般是PathClassLoader,PathClassLoader的父classloader是BootClassLoader.
2. when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).
2011年10月31日星期一
mistaken usage of a core class
Android工程在编译生成dex文件时dx有时候会出现下面的错误信息:
2.2-froyo中是
trouble processing "javax/Foo.class":
Attempt to include a core class (java.* or javax.*) in something other than a core library.......
2.3-gingerbread中是
trouble processing "javax/Foo.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
原因是从安全性和完整性考虑,Android(Java有吗?)不允许从外部引用Java的核心库(java.*或javax.*)。更详细的解释参考http://code.google.com/p/android/issues/detail?id=13084#c2。
但其实并不是所有的javax.*都不允许。dx的代码com/android/dx/command/dexer/Main.java中,保存了一个“黑名单”来过滤javax的包。
private static final String[] JAVAX_CORE = {
"accessibility", "crypto", "imageio", "management", "naming", "net",
"print", "rmi", "security", "sound", "sql", "swing", "transaction",
"xml"
};
那么如果Android并没有提供某些核心库而又必须要使用到这些库的情况下,该如何处理呢?一般来说都是通过repackage来重命名包。
1. 有源码的情况下,可以直接修改源代码。(通过ecllipse的改名重构是一个很好的方法)
2. 如果使用的第三方的jar包,则可以通过工具jarjar进行repackage。
2.2-froyo中是
trouble processing "javax/Foo.class":
Attempt to include a core class (java.* or javax.*) in something other than a core library.......
2.3-gingerbread中是
trouble processing "javax/Foo.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
原因是从安全性和完整性考虑,Android(Java有吗?)不允许从外部引用Java的核心库(java.*或javax.*)。更详细的解释参考http://code.google.com/p/android/issues/detail?id=13084#c2。
但其实并不是所有的javax.*都不允许。dx的代码com/android/dx/command/dexer/Main.java中,保存了一个“黑名单”来过滤javax的包。
private static final String[] JAVAX_CORE = {
"accessibility", "crypto", "imageio", "management", "naming", "net",
"print", "rmi", "security", "sound", "sql", "swing", "transaction",
"xml"
};
那么如果Android并没有提供某些核心库而又必须要使用到这些库的情况下,该如何处理呢?一般来说都是通过repackage来重命名包。
1. 有源码的情况下,可以直接修改源代码。(通过ecllipse的改名重构是一个很好的方法)
2. 如果使用的第三方的jar包,则可以通过工具jarjar进行repackage。
2011年10月27日星期四
Android framework注册native方法流程
Android framework有许多使用JNI的地方,但与一般的应用程序注册方法有所不同,framework中通过startReg()统一进行注册。startReg()函数的实现在AndroidRuntime.cpp。
startReg()调用register_jni_procs(gRegJNI, NELEM(gRegJNI), env)。其中 gRegJNI是一个数组,保存各个java类对应的native犯法注册函数的指针。
以BinderProxy为例:
native方法的注册函数是android_util_Binder.cpp的register_android_os_Binder(),这个函数保存在gRegJNI中。经过层层调用后,最终使用jni的RegisterNatives()来完成注册。
android_util_Binder.cpp的register_android_os_Binder() --->
android_util_Binder.cpp的int_register_android_os_BinderProxy() --->
AndroidRuntime::registerNativeMethods() --->
JNIHelp.c的jniRegisterNativeMethods() --->
jni的RegisterNatives()
RegisterNatives所需要的参数是静态变量保存:
android_util_Binder.cpp中,
char* kBinderProxyPathName保存类名
JNINativeMethod gBinderProxyMethods[]保存类中方法的名字、signatures、native方法的指针。
startReg()调用register_jni_procs(gRegJNI, NELEM(gRegJNI), env)。其中 gRegJNI是一个数组,保存各个java类对应的native犯法注册函数的指针。
以BinderProxy为例:
native方法的注册函数是android_util_Binder.cpp的register_android_os_Binder(),这个函数保存在gRegJNI中。经过层层调用后,最终使用jni的RegisterNatives()来完成注册。
android_util_Binder.cpp的register_android_os_Binder() --->
android_util_Binder.cpp的int_register_android_os_BinderProxy() --->
AndroidRuntime::registerNativeMethods() --->
JNIHelp.c的jniRegisterNativeMethods() --->
jni的RegisterNatives()
RegisterNatives所需要的参数是静态变量保存:
android_util_Binder.cpp中,
char* kBinderProxyPathName保存类名
JNINativeMethod gBinderProxyMethods[]保存类中方法的名字、signatures、native方法的指针。
订阅:
博文 (Atom)