- 论坛徽章:
- 3
|
本帖最后由 mci2004 于 2012-10-28 02:02 编辑
@starwing83 序哥,今天晚上又仔细看了下代码,发现代码中似乎不可能出现我昨天说的情况----在手机看到的乱码就是latin1编码。
1,
首先,可以确定你说的是对的,在vim上打个一个mp3文件看到的乱码确实是latin1,为此我特地去查了ISO-8859-1,也就说明了一个文件在vim上如果它不认识直接就当作latin1来转了。而且latin1是单字节的。
2,
关于locale的问题,我也查看了代码,locale信息的确定实际上通过jdk里面的Local类来确定的。这个Locale的确定又和android的系统属性有关。还记得我们昨天看到的那个函数吗?- // if the locale encoding matches, then assume we have a native encoding.
- if (encoding & mLocaleEncoding)
复制代码 事实上这个函数是做一个double check后面一个mLocalEncoding是通过android系统在java层获得的。前面一个encoding是通过findPossibleEncoding()---查巨表的函数获得的。如果这两个相等就非常确定可以是四种字符集中的某一个了,就可以交给下面的conertValues()了。
3,
回到最开始的问题,我为什么可以确定latin1编码不可能出现呢?因为,我看到了下面的代码
还记得endFile()这个函数吧?在没有比配成功字符集后,会直接交给上层去处理,也就是下面的逻辑- // if the locale encoding matches, then assume we have a native encoding.
- if (encoding & mLocaleEncoding)
- convertValues(mLocaleEncoding);
- // finally, push all name/value pairs to the client
- for (int i = 0; i < mNames->size(); i++) {
- status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i));
- if (status) {
- break;
- }
复制代码 convertValues没有机会执行,那么直接handleSringTag,这个时候那个传过来的字符(乱码那个)被当作一个字符串传进了handleString里(没做任何处理)。
//序哥下面是最后一个函数handleStringTag,主要关注value参数,它是乱码- virtual status_t handleStringTag(const char* name, const char* value)
- {
- ALOGV("handleStringTag: name(%s) and value(%s)", name, value);
- jstring nameStr, valueStr;
- if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
- mEnv->ExceptionClear();
- return NO_MEMORY;
- }
- // Check if the value is valid UTF-8 string and replace
- // any un-printable characters with '?' when it's not.
- char *cleaned = NULL;
- //判断是不是utf-8原理很简单,看单个字节是否在0x80-->0xBF之间,序哥这里有什么要补充的吗?
- if (utf8_length(value) == -1){
- cleaned = strdup(value);
- char *chp = cleaned;
- char ch;
- while ((ch = *chp)) {
- if (ch & 0x80) {
- //看这里,如果不是utf-8且字符在0x80之后,就认为是unprintable,然后设置成‘?’。
- *chp = '?';
- }
- chp++;
- }
- value = cleaned;
- }
- valueStr = mEnv->NewStringUTF(value);
- free(cleaned);
- if (valueStr == NULL) {
- mEnv->DeleteLocalRef(nameStr);
- mEnv->ExceptionClear();
- return NO_MEMORY;
- }
- mEnv->CallVoidMethod(
- mClient, mHandleStringTagMethodID, nameStr, valueStr);
- mEnv->DeleteLocalRef(nameStr);
- mEnv->DeleteLocalRef(valueStr);
- return checkAndClearExceptionFromCallback(mEnv, "handleStringTag");
- }
复制代码 所以我觉得应该会被显示成'?'才对啊。难道序哥,这个字符传到java层会被转换城latin1吗?不可能吧,java的文档我查了,没有这个说法啊?
但是我肯定我在手机上看到的那个乱码是latin1. |
|