利用 Android 源碼降狠,輕松實現(xiàn)漢字轉拼音功能

今天和大家分享一個從Android系統(tǒng)源代碼提取出來的漢字轉成拼音實現(xiàn)方案磷杏,只要一個類溜畅,560多行代碼就可以讓你輕松實現(xiàn)漢字轉成拼音的功能,且無需其他任何第三方依賴极祸。

需求場景

實際開發(fā)過程中需要用到實現(xiàn)漢字轉成拼音的場景比較常見慈格,如:通訊錄里的聯(lián)系人字母導航欄,為沒有設置頭像的用戶生成一個名字首字母的頭像遥金,國家(省份浴捆、城市)字母導航欄,搜索關鍵字轉換成拼音等稿械。

實現(xiàn)方案

Android平臺上將漢字轉換成為拼音已經有一些開源的第三方實現(xiàn)方案选泻,如pinyin4j和TinyPinyin

pinyin4j:https://sourceforge.net/projects/pinyin4j

TinyPinyin:https://github.com/promeG/TinyPinyin

以上這兩個實現(xiàn)方案,都需要引入不少類以及一些相應的編碼文件美莫,這里和大家介紹一個比上面兩個方案還要精簡的實現(xiàn)方案页眯,只要560行代碼且無需依賴于其他任何編文件的實現(xiàn)。這個類是從Android系統(tǒng)通訊錄源碼中提取的厢呵,類名為HanziToPinyin窝撵,其類文件路徑如下:

/packages/providers/ContactsProvider/src/com/android/providers

/contacts/HanziToPinyin.java

這是一個很獨立的類,需要使用的項目直接拷貝到自己對應的工程里面即可使用述吸,需要注意的是忿族,我是在Android 4.2.2的系統(tǒng)源碼中拷貝出來的锣笨,為什么選擇4.2.2,一個是4.2.2之后(4.3開始)的HanziToPinyin不再可以獨立使用道批,需要依賴于Transliterator错英,而這個類我們是無法直接引用的。

而Android 2.x的HanziToPinyin在測試了很多轉換的結果發(fā)現(xiàn)是錯誤的隆豹,所以選擇了最后一個可以采納使用的版本Android 4.2.2椭岩。

如何使用

HanziToPinyin這個類的代碼量非常少,結構也非常簡單

下面簡單的說明一下如何使用璃赡,非常簡單判哥,只需要把需要轉換的漢字傳入get方法即可獲取返回的拼音結果

其返回的數據結構是一個HanziToPinyin.Token的ArrayList,HanziToPinyin.Token是HanziToPinyin中的一個公共靜態(tài)外部類碉考,

其分別有type塌计、source、target等三個成員變量侯谁,type是標識token的類型锌仅,有三種不同的取值1(拉丁文),2(拼音)墙贱,3(未知)热芹,source是輸入的中文,target則是中文轉換后對應的拼音惨撇。這里還有一個細節(jié)需要注意一下伊脓,只拷貝HanziToPinyin在原生系統(tǒng)上使用是沒有問題的,但是在國產手機的ROM上則無法正常使用魁衙,需要加上下面三行代碼做適配:

否則HanziToPinyin的初始化狀態(tài)會設置錯誤报腔,而導致無法實現(xiàn)漢字轉換成拼音。

內部實現(xiàn)

了解完如何使用后纺棺,我們來簡單窺探一下HanziToPinyin內部是如何實現(xiàn)的榄笙,先來看一下類中比較耀眼的兩個數組UNIHANS和PINYINS(兩個類很長,截圖沒截全祷蝌,大家自己看代碼吧)

其中UNIHANS是一組漢字對應的unicode編碼茅撞,而PINYINS則是UNIHANS中每個元素對應的拼音的ASCII碼,如UNIHANS的第一個元素是\u963f巨朦,其對于的中文是米丘,換成拼音則是A,而A對應的ASCII碼用十進制表示則是65糊啡,對應的就是PINYINS的第一個數組中的第一個元素拄查,至于為什么后面有5個0的元素,主要是因為漢字的拼音最長的有六個字母(例如:chuang)棚蓄,而只有一個a堕扶,所以后面的5個空位就需要用0來填充了碍脏。我們在調用get方法時將中文以String的形式傳入,方法內部會遍歷String中的每個元素稍算,為其生成對應的Token典尾,也就是我們最后拿到的那個ArrayList中的結果。

所以最關鍵的實現(xiàn)是在getToken方法中糊探,這里忽略getToken前面的30來行判斷代碼钾埂,直接看關鍵部分

通過二分檢索的方式,使用java.text.Collator的compare方法不斷比對UNIHANS數組中與輸入的漢字同音(注意:這里是同音不是完全相同)的字科平,最終獲取其對應的在UNIHANS數組中的下標位置offset褥紫。前面我們提到UNIHANS和PINYINS是相互對應的,所以這里也能找到PINYINS中對應讀音的一組ASCII碼瞪慧,通過int轉換成char髓考,再使用StringBuilder進行拼接,就可以獲取對應的拼音了汞贸,實現(xiàn)思路上還是很簡單清晰的绳军。

性能和不足

在性能上印机,HanziToPinyin還是比較客觀的矢腻,畢竟用了二分檢索,在實際測試過程中丟了一篇5500多字的文章進行轉換射赛,只用了415ms多柑;

在準確率上,拿了一堆人名和一個國家列表數據進行轉換楣责,隨機抽取數據都沒有發(fā)現(xiàn)出錯的數據竣灌,但是按照這個類的實現(xiàn)上看,如果輸入的漢字拼音不與UNIHANS中任何一個元素同音秆麸,則必然無法得到正確的結果初嘹,實際測試中,我隨便拿了一些數據測試都沒有得到不正確的結果輸出沮趣,不知道得多生僻的字才能得出個錯誤結果屯烦;

HanziToPinyin這類并不支持多音字,所以如果一定要考慮多音字的問題房铭,這個類就不適合了驻龟;

總結

關于HanziToPinyin就介紹到這里,我已經將這個類的代碼我已經整理放在Gist上(https://gist.github.com/D-clock/7a6e33f42c0177439a49d85b73f1e600)缸匪,需要的同學自取 翁狐,如果HanziToPinyin不能滿足你的需求,那可以考慮使用前面提到的pinyin4j和TinyPinyin凌蔬。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末露懒,一起剝皮案震驚了整個濱河市闯冷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌懈词,老刑警劉巖窃躲,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钦睡,居然都是意外死亡蒂窒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門荞怒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洒琢,“玉大人,你說我怎么就攤上這事褐桌∷ヒ郑” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵荧嵌,是天一觀的道長呛踊。 經常有香客問我,道長啦撮,這世上最難降的妖魔是什么谭网? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮赃春,結果婚禮上愉择,老公的妹妹穿的比我還像新娘。我一直安慰自己织中,他們只是感情好锥涕,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狭吼,像睡著了一般层坠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刁笙,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天破花,我揣著相機與錄音,去河邊找鬼采盒。 笑死旧乞,一個胖子當著我的面吹牛,可吹牛的內容都是我干的磅氨。 我是一名探鬼主播尺栖,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烦租!你這毒婦竟也來了延赌?” 一聲冷哼從身側響起除盏,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挫以,沒想到半個月后者蠕,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡掐松,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年踱侣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大磺。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡抡句,死狀恐怖,靈堂內的尸體忽然破棺而出杠愧,到底是詐尸還是另有隱情待榔,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布流济,位于F島的核電站锐锣,受9級特大地震影響,放射性物質發(fā)生泄漏绳瘟。R本人自食惡果不足惜雕憔,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稽荧。 院中可真熱鬧橘茉,春花似錦、人聲如沸姨丈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蟋恬。三九已至,卻和暖如春趁冈,著一層夾襖步出監(jiān)牢的瞬間歼争,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工渗勘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沐绒,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓旺坠,卻偏偏與公主長得像乔遮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子取刃,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,849評論 25 707
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程蹋肮,因...
    小菜c閱讀 6,375評論 0 17
  • 我女兒叫張紫暄出刷,名字還是我起的呢,她爸爸希望她像太陽一樣積極陽光坯辩,所以是日字旁的暄馁龟。 離婚四年了,中間很少見面漆魔,跟...
    周海雙閱讀 252評論 0 0
  • 1 陽春三月,乍暖還寒雀摘,萬物又要開始新一季的輪回裸删。握筆許久又怕言過其實,我思故我在阵赠,怕到底是沒什么用涯塔。...
    A賈瑞朙閱讀 232評論 0 2
  • 這天氣熱的就像有人提前預支了夏天,一樣清蚀,
    渲染星晴閱讀 92評論 0 0