安卓中的乱码以及编码问题
?Android亂碼以及編碼轉化
?????To live is to function,that is all there is in living.
????? 亂碼是安卓開發中常常遇到的事情,AndroidStudio默認的是UTF-8編碼,而網站常用GBK(GB2312老版)編碼,為了避免網絡請求出現問題,常常會對網絡接口中的的文字進行編碼,也會對返回的數據進行編碼,如何在UTF-8的環境下將漢字成功的轉換成其他編碼尼,這是該篇博客為讀者解答的事情,讀完此篇博客,你將對編碼有新的認識,從此亂碼與你是路人,編碼不在是難事,此篇博客乃一家之言,若有問題請直言以待校正。
??? 首先,介紹一下編碼,解碼的概念,以及為什么要編碼 ? 。
編碼:將源對象內容按照一種標準轉換為一種標準格式內容。 解碼:和編碼對應的,它使用和編碼相同的標準將編碼內容還原為最初的對象內容。 編解碼的目的最初是為了加密信息,經過加密的內容不知道編碼標準的人很難識別,已經有數千年歷史了。 而現在編解碼種類非常多,主要目的則是為了信息交換。 除了加密,目前程序中常見的如字符編解碼,HTML編解碼,URL編解碼,郵件編解碼,多媒體編解碼等。編碼是為了符合傳輸的要求,解碼是為了還原成我們能識別的信息。 例如字符編解碼,字符編碼在一系列數字與人們將文本輸入到計算機中時希望看到的字符之間提供映射。因為世界上有不同的語言和文字,所以需要將不同的文字編碼以通過計算機處理和傳輸。 再比如多媒體編解碼,因為有多種不同格式的圖像聲音,所以它們各自有自己編解碼標準。 ?? 那么今天我們主要處理安卓中的文字編碼解碼問題,至于加密在后續文章我將會提到。?? 介紹一個工具——站長工具之編碼轉換http://tool.chinaz.com/tools/utf-8.aspx 可以將經行多種編碼之間的轉換,當然站長工具還有其他功能,君可慢慢細看
??????? 我需要的編碼:
??????? 已知曉的文字:動漫卡通
后臺需要的編碼為:%25u52A8%25u6F2B%25u5361%25u901A
?????? 接下來使用站長工具進行編碼處理,如下圖:
????? 一:直接使用UrlEncode
? 可以看見其對應的編碼是:%e5%8a%a8%e6%bc%ab%e5%8d%a1%e9%80%9a,這和我們的需求相差很遠,那么如果再一次進行編碼會不會達到我們的期望尼,接下來拭目以待:
?? 二次UrlEncode對應的編碼是:%25e5%258a%25a8%25e6%25bc%25ab%25e5%258d%25a1%25e9%2580%259a,所以簡單的
URLEncode.encode()方法并不能達到需求,那么怎么辦尼
?? 接下來仍然使用站長工具,復制“動漫卡通”,測試其他編碼是否能實現。。。終于在使用GBK——UTF-8的時候我看見了希望。
?? 待編碼文字:動漫卡通????? 需得到的編碼:%25u52A8%25u6F2B%25u5361%25u901A
?? 目前通過GBK轉UTF-8可以達到:动漫卡通
?? 同志們有沒有覺得革命已經勝利了尼!數字部分已經出來了,如果String.replace(“&#x”,“25u%”)來替換便可以實現目的,但是國內網站的中文環境是多數是GBK(GBK2312),而studio的環境默認的是utf-8,如何在UTF-8的環境下實現這一轉變尼?
?? 接下來我們需要了解一個新的知識:Uniconde編碼。
? 什么是Unicode編碼尼?請看下圖(來源于百度百科)
???
??
??Unicode 是為了解決傳統的字符編碼方案的局限而產生的,例如ISO 8859所定義的字符雖然在不同的國家中廣泛地使用,可是在不同國家間卻經常出現不兼容的情況。很多傳統的編碼方式都有一個共同的問題,即容許電腦處理雙語環境(通常使用拉丁字母以及其本地語言),但卻無法同時支持多語言環境(指可同時處理多種語言混合的情況)。 ??? Unicode 編碼包含了不同寫法的字,如“ɑ/a”、“戶/戶/戸”。然而在漢字方面引起了一字多形的認定爭議(詳見中日韓統一表意文字主題)。 ??? 在文字處理方面,統一碼為每一個字符而非字形定義唯一的代碼(即一個整數)。換句話說,統一碼以一種抽象的方式(即數字)來處理字符,并將視覺上的演繹工作(例如字體大小、外觀形狀、字體形態、文體等)留給其他軟件來處理,例如網頁瀏覽器或是文字處理器。 ??? 幾乎所有電腦系統都支持基本拉丁字母,并各自支持不同的其他編碼方式。Unicode為了和它們相互兼容,其首256字符保留給ISO 8859-1所定義的字符,使既有的西歐語系文字的轉換不需特別考量;并且把大量相同的字符重復編到不同的字符碼中去,使得舊有紛雜的編碼方式得以和Unicode編碼間互相直接轉換,而不會丟失任何信息。舉例來說,全角格式區段包含了主要的拉丁字母的全角格式,在中文、日文、以及韓文字形當中,這些字符以全角的方式來呈現,而不以常見的半角形式顯示,這對豎排文字和等寬排列文字有重要作用。????? 在表示一個Unicode的字符時,通常會用“U+”然后緊接著一組十六進制的數字來表示這一個字符。在基本多文種平面(英文為 Basic Multilingual Plane,簡寫 BMP。它又簡稱為“零號平面”, plane 0)里的所有字符,要用四位十六進制數(例如U+4AE0,共支持六萬多個字符);在零號平面以外的字符則需要使用五位或六位十六進制數了。舊版的Unicode標準使用相近的標記方法,但卻有些微的差異:在Unicode 3.0里使用“U-”然后緊接著八位數,而“U+”則必須隨后緊接著四位數。[1]
???
?? 總結也就一句話,Unicode可以實現與各種編碼之間相互轉化。他就像一個父類,有了多個兒子,兒子各不相同,但都流傳著父親的基因。
? 知道了這一點接下來我們就可以開始干了,捋一捋思路,我們首先將utf-8環境下的“動漫卡通”轉化為Unicode編碼下A,然后再講A轉換為GBK編碼下的B(得到純正的GBK編碼),然后在將B轉換為Unicode編碼下的C;
接下來我們試一試是不是這樣尼,我們打印出一條日志:
03-12 17:12:55.869 23869-23869/com.itwangxia.hackhome I/----GAME->>>>: encodeUTF: 動漫卡通?? utf2gbk = \U52A8\U6F2B\U5361\UFFFF901A???? utf2unicode = \U52A8\U6F2B\U5361\UFFFF901A
可以發現,我們在將UTF編碼轉為Unicode編碼下的B的時候已經得到了需要的編碼(排除\U以及FFFF的干擾)
至于為什么是這樣,我將在下一篇博客中介紹編碼的問題。
實現了諸如%25u52A8%25u6F2B%25u5361%25u901A此類的編碼。
接下來粘貼代碼,主要是其他編碼轉換為Unicode編碼,至于編碼之間互相轉換還是借助Unicode編碼來實現的。
? /** *將GBK編碼轉換為UTF-8編碼 * */ public String gbk2utf8(String gbk) { String l_temp = GBK2Unicode(gbk);l_temp = unicodeToUtf8(l_temp);return l_temp;} /** *將UTF-8編碼轉換為GBK編碼 * */ public static String utf82gbk(String utf) { String l_temp = utf8ToUnicode(utf);l_temp = Unicode2GBK(l_temp);return l_temp;} /** *將gbk編碼轉換為unicode編碼 *主要編碼方法 */public static String GBK2Unicode(String str) {??????????? StringBuffer result = new StringBuffer();??????????? for (int i = 0; i < str.length(); i++) {??????????????? char chr1 = (char) str.charAt(i);??????????????? if (!isNeedConvert(chr1)) {????????? ??????????result.append(chr1);??????????????????? continue;??????????????? }??????????????? result.append("\\u" + Integer.toHexString((int) chr1));??????????? }??????????? return result.toString();??????? }???????
/** *將Unicode編碼轉換為GBK編碼 *主要解碼方法 */ public static String Unicode2GBK(String dataStr) {int index = 0;StringBuffer buffer = new StringBuffer();int li_len = dataStr.length();while (index < li_len) {if (index >= li_len - 1|| !"\\u".equals(dataStr.substring(index, index + 2))) {buffer.append(dataStr.charAt(index));index++;continue;}String charStr = "";charStr = dataStr.substring(index + 2, index + 6);char letter = (char) Integer.parseInt(charStr, 16);buffer.append(letter);index += 6;}return buffer.toString();}public static boolean isNeedConvert(char para) {return ((para & (0x00FF)) != para);}/** *將UTF-8編碼轉換為Unicode編碼 *主要編碼方法 */????? public static String utf8ToUnicode(String inStr) {char[] myBuffer = inStr.toCharArray();StringBuffer sb = new StringBuffer();for (int i = 0; i < inStr.length(); i++) { //?? ?????????????char ch=myBuffer[i]; //??????????????? if((int)ch < 10){ //??????????????????? sb.append("\\u000"+(int)ch); //??????????????????? continue; //??????????????? }UnicodeBlock ub = UnicodeBlock.of(myBuffer[i]);if (ub == UnicodeBlock.BASIC_LATIN) {sb.append(myBuffer[i]);} else if (ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {int j = (int) myBuffer[i] - 65248;sb.append((char) j);??????????????} else {short s = (short) myBuffer[i];String hexS = Integer.toHexString(s);String unicode = "\\u" + hexS;sb.append(unicode.toUpperCase());}?????????? }return sb.toString();}/** *將UTF-8編碼轉換為GBK編碼 *主要解碼方法 */?????? public static String unicodeToUtf8(String theString) {char aChar;int len = theString.length();StringBuffer outBuffer = new StringBuffer(len);for (int x = 0; x < len;) {aChar = theString.charAt(x++);if (aChar == '\\') {aChar = theString.charAt(x++);?????????????????? if (aChar == 'u') {// Read the xxxxint value = 0;for (int i = 0; i < 4; i++) {aChar = theString.charAt(x++);????switch (aChar) {case '0':case '1':case '2':case '3':case '4':???????case '5':case '6':case '7':case '8':case '9':value = (value << 4) + aChar - '0';break;case 'a':case 'b':case 'c':case 'd':case 'e':??????????????????????????????case 'f':value = (value << 4) + 10 + aChar - 'a';break;case 'A':case 'B':????????????????????case 'C':case 'D':case 'E':case 'F':value = (value << 4) + 10 + aChar - 'A';?????????????break;default:throw new IllegalArgumentException("Malformed?? \\uxxxx?? encoding.");}???????????}outBuffer.append((char) value);} else {if (aChar == 't')aChar = '\t';else if (aChar == 'r')?aChar = '\r';else if (aChar == 'n')aChar = '\n';else if (aChar == 'f')aChar = '\f';outBuffer.append(aChar);??????}} elseoutBuffer.append(aChar);}return outBuffer.toString();}
接下來介紹一些其他方法以幫助瀏覽此博文的朋友:
??
try {String s = new String("卡通動漫".getBytes(), "GBK"); } catch (UnsupportedEncodingException e) {e.printStackTrace(); } 該方法是不可取的,得到的是亂碼,不建議使用而如果像是這種亂碼进入游戏→点左上角头像→兑换码
使用
Html.fromHtml(String.format(formate,gDesc))就足以搞定了,主要是后臺防止文字亂碼問題。
javaScript中的常用escape()編碼 和unescape()解碼
???? escape編碼,例如中文:網俠小鮮肉? escape編碼為:%u7f51%u4fa0%u5c0f%u9c9c%u8089
???unescape解碼
????????????? 這時我們只需要在在escape編碼里面將“%u”換成“%25u”即可
(以上是我個人開發中面對的一些問題及困惑,若有誤導,望君海涵,也望君扶正,謝謝)
??
總結
以上是生活随笔為你收集整理的安卓中的乱码以及编码问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 接口的创建及使用
- 下一篇: SQLSERVER EXCEPT运算符=