之前寫過一篇博客漢字轉(zhuǎn)拼音開源工具包Jpinyin介紹燕偶,介紹過JPinyin的使用侵浸,因?yàn)樗鼘?shí)在是太方便了旺韭,在項(xiàng)目一直用它,但是最近在做項(xiàng)目的時候掏觉,發(fā)現(xiàn)使用了JPinyin的工程区端,在IDE中編譯的APK能正常使用,但是APK被加密后再安裝履腋,使用JPinyin時會報漢字轉(zhuǎn)拼音時讀取數(shù)據(jù)失敗珊燎,下面記錄一下問題的解決過程。
加密后導(dǎo)致使用Jpinyin報異常的原因肯定是加密導(dǎo)致了Jpinyin中的某些內(nèi)容變化導(dǎo)致(解密后數(shù)據(jù)不再是未加密前的數(shù)據(jù)了)遵湖,為了跟蹤這個問題悔政,下載JPinyin的源碼發(fā)現(xiàn)漢字轉(zhuǎn)拼音是使用了三個“數(shù)據(jù)庫”文件,分別是:
chinese.db
mutil_pinyin.db
pinyin.db
起初我以為是數(shù)據(jù)被加密了延旧,加密APK的時候相當(dāng)于這些數(shù)據(jù)被再次加密導(dǎo)致了JPinyin不能正常使用谋国,但是JPinyin中的代碼是這樣讀取這三個文件的,讀取文件的類為:PinyinResource.java
package com.github.stuxuhai.jpinyin;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 資源文件加載類
*
* @author stuxuhai (dczxxuhai@gmail.com)
* @version 1.0
*/
public class PinyinResource {
private static Properties getResource(String resourceName) {
InputStream is = PinyinResource.class.getResourceAsStream(resourceName);
Properties props = new Properties();
try {
props.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
is.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return props;
}
protected static Properties getPinyinTable() {
String resourceName = "/data/pinyin.db";
return getResource(resourceName);
}
protected static Properties getMutilPintinTable() {
String resourceName = "/data/mutil_pinyin.db";
return getResource(resourceName);
}
protected static Properties getChineseTable() {
String resourceName = "/data/chinese.db";
return getResource(resourceName);
}
}
文件讀取過程中根本沒有數(shù)據(jù)庫的解密過程迁沫,代碼中將db文件當(dāng)做“.properties”文件處理了芦瘾,遂在網(wǎng)上查詢".properties"為何物:JAVA操作properties文件,直接把這三個db文件的后綴改成".properties"集畅,然后打開的內(nèi)容是這樣的:

于是可以確定這三個文件的原始格式為".properties"近弟,只是作者將其改為".db"文件了,于是嘗試通過將db格式改為.properties,來解決加密APK導(dǎo)致JPinyin不能正常使用的問題挺智,修改后的代碼是這樣的(這個工程是在Android項(xiàng)目中被使用的祷愉,所以我將這三個.properties文件放在了assets文件夾下):
/**
* 資源文件加載類
*
* @author stuxuhai (dczxxuhai@gmail.com)
* @version 1.0
*/
public class PinyinResource {
private static Properties getResource(Context context, String resourceName) {
InputStream is = null;
Properties props = null;
try {
is = context.getAssets().open(resourceName);
props = new Properties();
props.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(null != is){
is.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return props;
}
protected static Properties getPinyinTable(Context context) {
String resourceName = "pinyin.properties";
return getResource(context, resourceName);
}
protected static Properties getMutilPintinTable(Context context) {
String resourceName = "mutil_pinyin.properties";
return getResource(context, resourceName);
}
protected static Properties getChineseTable(Context context) {
String resourceName = "chinese.properties";
return getResource(context, resourceName);
}
}
JPinyin的其它幾個類也需要修改,加上context參數(shù)赦颇,修改后重新打包JPinyin.jar二鳄,在IDE中運(yùn)行沒問題,加密后使用也沒有問題媒怯。將properties文件改成db文件導(dǎo)致加密后不能正常使用的問題我還沒有跟蹤到具體原因订讼,但解決這個問題的過程和方法值得記錄一下,遇到這種問題最好的辦法是查看源碼扇苞,大膽猜測并嘗試欺殿,比在不看源碼的情況下去猜測要靠譜得多寄纵。