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。

*现在的 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).