青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

xiaoguozi's Blog
Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····
android軟件破解的工具:
smali.jar——google官方提供,主要作用是把smali文件打包成class.dex文件
baksmali.jar——google官方提供,主要作用是把*.odex文件反編譯為smali文件
apktool.jar——第三方提供?用于解析*.apk文件,生成smali文件和解析資源文件
signapk.jar——apk簽名工具
ddms——ADT中的一個調試工具


破解工具的使用方法:
http://sin90lzc.iteye.com/blog/1198173


除了這些破解工具之外,還需要對smali語法有一定的了解。下面的網址對smali的語法有詳細的說明:
http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html


最后,最好對Android的應用開發有一定的了解,至少對Android的四大組件有深刻的認識:Activity,Service,ContentProvider,BroadcastReceiver


Android應用程序在某些機器上不能運行、崩潰的原因不外乎以下幾點:
原因一:該應用程序需要依賴于生產廠商的框架(像三星,它對android的framework做過大量的修改)
錯誤提示:找不到field,找不到對應的方法,找不到相應的類
解決途徑:
1.在smali中嘗試屏蔽掉相應的field,method,或類的調用,然后進行大量測試,確保不影響正常使用
2.反編譯framework,找到缺少的field,method,類的相應smali文件,根據smali文件編寫java源碼。(當smali文件比較小的時候,這個方法才可行,否則盡量避免用這種方法)
3.實在無招的情況下,只能把第三方的framework的smali文件復制到自己的framework里面(非常槽糕的方法)。
4.對于應用程序需要依賴第三方低層的功能實現時,而我們的低層卻沒有這樣的功能(比如說視頻通話等),此時可以使用上面的方法一解決,也可以參考技術四。


原因二:資源文件不存在,像color,drawable,string等等的資源
錯誤提示:資源文件找不到
解決途徑:
在技巧一中有詳細說明。


原因三:應用程序需要一些函數庫的支持(在目錄/system/lib中缺少相應的函數庫)。
錯誤提示:一般都會拋出UnSatisfiedException異常,后面緊跟所缺函數庫的庫名。
解決途徑:
1.在第三方的函數庫中找到對應的so文件,然后復制到自己的函數庫中。
2.如果函數庫與函數庫之間有著各種耦合的時候,方法一可能就會不適用了(看運氣唄)。這時候就只能反編譯so文件了(這個是C/C++的反編譯的應用了,需要再學習)


原因四:應用程序沒有相應的權限
錯誤提示:nopermission
解決途徑:
1.在AndroidMenifest.xml文件中添加<user-permision />添加相應的權限


原因五:由于應用程序本身的一些安全機制或條件判斷影響程序的表現
解決途徑:
1.反編譯成smali文件,使用技巧三的方法跟蹤程序的運行,耐心地分析程序的邏輯,找到可疑smali代碼,屏蔽或修改代碼。


原因六:數據庫的結構不一樣
錯誤提示:缺少某個字段或類型不匹配
場情:比如android的音樂播放器與三星的音樂播放器,它們的數據庫結構由MediaProvider.apk這個包提供。然而兩者在MediaProvider.apk中關于數據庫結構的定義是不一樣的,三星音樂播放器需要更多的字段去保存信息。
解決途徑:
1.拿上面場情為例,反編譯MediaProvider.apk,從smali文件中找到組件ContentProvider的定義(smali文件), 在該smali文件中找到關于SQL生成表結構的字符串(如:create table...),修改該SQL語句來適合三星音樂播放器的需要,然后重新打包回apk文件。


原因七:應用程序需要引用第三方提供商自定義的框架(比如,三星的/system/framework目錄下有twframework.jar、twframework-res.apk,這個就是三星的UI框架)

錯誤提示:
解決途徑:
1.屏蔽AndroidMenifest.xml文件中<uses-library android:name="sec_feature" />的代碼,一般這樣改動是不可行的。
2.在/system/etc/permission目錄下添加庫的聲明,如添加touchwiz.xml文件,文件內容如下:
<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <library name="touchwiz" file="/system/framework/twframework.jar"/>
</permissions>
最后,還需要把三星的twframework.jar、twframework-res.apk復制到/system/framework目錄下

反編譯或破解的技巧總結:
一、對無應用程序源碼的情況下,對資源文件的增刪改。
概述:在無程序源碼,不重新編譯的情況下,刪除或修改資源文件都是非常簡單的一件事情,網上也有很多的文章提到過。但是網上卻找不到在不重新編譯的情況下添加資源文件的方法。
在不重新編譯的情況下添加資源文件的步驟:
1.按正常的應用程序開發添加資源。比如,要添加一個string資源,在values/strings.xml上加上:
<string name="newstring">content</string>


2.一個編譯后的apk會在values目錄下多生成了一個public.xml文件,這個文件記錄了每個資源的引用編號。以添加string資源為例, 在public.xml文件中找到<public type="string" ...>中最后一個元素,在這個元素后添加
<public type="string" name="newstring" id="0x7f0700a0" /><!--此時id就是string資源newstring的引用編號,注意該id應該是public.xml文件中是唯一值-->


3.修改smali文件,使用新增的資源
invoke-virtual {p0}, Lcom/sini/SfsdfsActivity;->getResources()Landroid/content/res/Resources;


move-result-object v0


const v1, 0x7f0700a0


invoke-virtual {v0, v1}, Landroid/content/res/Resources;->getString(I)Ljava/lang/String;


二、編寫smali文件
概述:自己一手一腳去寫smali文件是件超級困難的事情,如何快速地得到smali代碼呢?
技巧:使用eclipse開發工具,新建一個Android項目,用正常的開發方式寫一段java代碼(這個代碼就是你想在smali中完成的東西)。使 用eclipse的run->Android Application選項 生成apk文件,再把apk文件反編譯,找到需要的smali代碼,然后復制這段代碼到需要的地方。NOTIC:復制的時候需要注意smali的變量 v0,v1...的正確性。


三、跟蹤程序運行
概述:沒源碼=寸步難行!為了能跟蹤無源碼的apk程序的運行,只能辛苦地修改smali添加跟蹤信息了。值得慶幸的是,android本身自帶有方便的日志API(Log.i()\Log.w()...);
技巧:按技巧二的方法得到Log.i()的smali代碼,然后把這段代碼插入到你想跟蹤信息的地方。


四、只修改smali中影響UI的代碼,保留功能代碼(適用于必須得把smali寫回java源碼的情況)
概述:這里最好的例子就是破解三星的通話界面。三星的通話界面程序Phone.apk中包含了視頻通話的功能,這個功能又需要依賴三星的一些低層實現。而 我們的系統中沒有視頻通話的功能,也沒有相應的低層實現。但Phone.apk的主要功能是打電話,而這個功能android本身就自帶的。也就是說三星 的Phone.apk與android的Phone.apk的核心功能是一樣的,只是UI不太一樣而已。此時應該只修改smali中的影響UI的代碼,屏 蔽掉
smali中對視頻通話的調用。
技巧:找到程序中影響UI的Actvity,然后根據smali文件的內容,寫java源碼
posted @ 2013-02-17 14:52 小果子 閱讀(3365) | 評論 (0)編輯 收藏
原文:
http://1622511.blog.51cto.com/1612511/581011

如果你要定制一個Android系統,你想用你自己的Launcher(Home)作主界面來替換Android自己的Home,而且不希望用戶安裝的Launcher來替換掉你的Launcher.
我們可以通過修改Framework來實現這樣的功能。

這里以Android2.1的源代碼為例來實際說明。

1)首先了解一下Android的啟動過程。
  Android系統的啟動先從Zygote開始啟動,然后......(中間的過程就不說了).....一直到了SystemServer(framework)這個地方,看到這段代碼:

      /**
     * This method is called from Zygote to initialize the system. This will cause the native
     * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
     * up into init2() to start the Android services.
     */
    native public static void init1(String[] args);

    public static void main(String[] args) {
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server");
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        System.loadLibrary("android_servers");
        init1(args);
    }

    public static final void init2() {
        Log.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }
}

從SystemServer的main函數開始啟動各種服務。
首先啟動init1,然后啟動init2.
從上面的注釋可以看到:init1這個方法時被Zygote調用來初始化系統的,init1會啟動native的服務如SurfaceFlinger,AudioFlinger等等,這些工作做完以后會回調init2來啟動Android的service。

這里我們主要來關注init2的過程。
init2中啟動ServerThread線程,
ServerThread中啟動了一系列的服務,比如這些:

ActivityManagerService
EntropyService
PowerManagerService
TelephonyRegistry
PackageManagerService
AccountManagerService
BatteryService
HardwareService
Watchdog
SensorService
BluetoothService
StatusBarService
ClipboardService
InputMethodManagerService
NetStatService
ConnectivityService
AccessibilityManagerService
NotificationManagerService
MountService
DeviceStorageMonitorService
LocationManagerService
SearchManagerService
FallbackCheckinService
WallpaperManagerService
AudioService
BackupManagerService
AppWidgetService

這些大大小小的服務起來以后,開始
 ((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady()
在systemReady后開始開始啟動Launcher。

在尋找Launcher的時候是根據HOME的filter(在Manifest中定義的<category android:name="android.intent.category.HOME" />)來過濾。
然后根據filter出來的HOME來啟動,如果只有一個HOME,則啟動這個HOME,如果用戶自己裝了HOME,那就會彈出來一個列表供用戶選擇。

我們現在希望從這里彈出我們自己定制的Launcher,同時也不希望彈出選擇HOME的界面,我們不希望用戶修改我們的home,比如我們的home上放了好多廣告,以及強制安裝的程序,不希望用戶把它干掉。

我們可以通過這樣來實現:

2) 定義一個私有的filter選項,然后用這個選項來過濾HOME.
   一般情況下我們使用Manifest中定義的<category android:name="android.intent.category.HOME"來過濾的,我們現在增加一個私有的HOME_FIRST過濾。

     在Intent.java(frameworks/base/core/java/android/content/Intent.java)中添加兩行代碼

    //lixinso:添加CATEGORY_HOME_FIRST
    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
    public static final String CATEGORY_HOME_FIRST = "android.intent.category.HOME_FIRST";

3)修改和CATEGORY_HOME相關的所有的地方,都改成HOME_FIRST,主要是framework中的這幾個地方:

    frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中
    //intent.addCategory(Intent.CATEGORY_HOME);
    改成intent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso:
    //if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
    改成if (r.intent.hasCategory(Intent.CATEGORY_HOME_FIRST)) { //lixinso: Intent.CATEGORY_HOME -> Intent.CATEGORY_HOME_FIRST
 
   frameworks/base/services/java/com/android/server/am/HistoryRecorder.java中
   // _intent.hasCategory(Intent.CATEGORY_HOME) &&
   改成 _intent.hasCategory(Intent.CATEGORY_HOME_FIRST) && //lixinso: Intent.CATEGORY_HOME->Intent.CATEGORY_HOME_FIRST

   frameworks/policies/base/mid/com/android/internal/policy/impl/MidWindowManager.java中
   //mHomeIntent.addCategory(Intent.CATEGORY_HOME); 
   改成 mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso
 
  frameworks/policies/base/mid/com/android/internal/policy/impl/RecentApplicationsDialog.java中
   //new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);
   改成 new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0); //lixinso

  frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java中
   //mHomeIntent.addCategory(Intent.CATEGORY_HOME);
   改成 mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso

  frameworks/policies/base/phone/com/android/internal/policy/impl/RecentApplicationsDialog.java中
   //ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);
   改成 ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0); //lixinso



4) 寫一個自己的Launcher.
   可以參考android sample中的Launcher,或者android源代碼中的 /packages/apps/Launcher 來寫。
   在Launcher中標記其是不是Launcher的最關鍵的代碼時Manifest中的filter:android:name="android.intent.category.HOME"
   現在我們定義了自己的filter,那么,我們在我們自己寫的Launcher中將Manifest改為:
    <application  android:process="android.process.acore3" android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".FirstAppActivity"
                  android:label="@string/app_name">
            <intent-filter>
                                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME_FIRST" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY" />
            </intent-filter>
        </activity>
    </application>

然后將編譯好的apk放到/out/target/product/generic/system/app目錄下。

5)將Android自帶的Launcher刪除掉,包括源代碼(packages/apps/Launcher)和apk(/out/target/product/generic/system/app/Launcher.apk)。

6)
做完這些工作,就可以重新編譯Android了,我們可以編譯修改過的幾個相關的包。
如果之前編譯過了Android源碼,可以用mmm命令來編譯部分的改動。
這里需要這樣編譯:

$ . build/envsetup.sh 
$ mmm frameworks/base
$ mmm frameworks/base/services/java
$ mmm frameworks/policies/base/mid
$ mmm frameworks/policies/base/phone

7)
編譯完成后重新生成img文件。
$ make snod

8) 現在可以啟動Android模擬器來看效果了。
首先設置環境變量:
$ export ANDROID_PRODUCT_OUT= ./out/target/product/generic
然后切換到
$ cd ./out/host/linux-x86/bin
運行
$ ./emulator

這樣我們啟動的模擬器里面用的image就是我們剛才編譯好的自己定制的東西了。
從模擬器上可以看到啟動的Launcher是我們自己的Launcher,不會出現默認的Launcher了,也不會出現選擇界面。

9)我們再驗證一下,如果用戶裝上了一個其他的Launcher(Home)會怎么樣。
  從網上找一個一般的Launcher或者自己寫一個一般的Launcher裝上去,重新啟動,不會出現選擇界面。
  按HOME鍵也不會出來兩個HOME來選擇。


這樣我們就牢牢控制了用戶的桌面。
只有我們自己定制的HOME才能裝上。 這對于定制Android設備的廠商很有用處。
posted @ 2013-02-17 14:51 小果子 閱讀(1527) | 評論 (0)編輯 收藏
要移植,就要了解系統的結構和打包解包:
打包很容易,只需要制作成ZIP格式的壓縮包就行了,里面包含2個文件夾和1個boot.img文件,boot.img是內核,沒有內核的系統是不能運行 的,另外兩個文件夾一個是system,也就是Android系統所在地,另一個是META-INF,這里一般存放是刷機腳本,我們移植一般需要改的就是 system文件夾里的內容。
解包就是解壓縮。
首先說結構,system下有:
App文件夾(存放內置軟件的地方,每個軟件都有自己的名字標注著,很容易識別,在移植上除USB.apk必須用咱們自己的版本以外,其他可以用同分辨率機型的APP直接替換)
Bin文件夾(本文件夾一般存放的是開機運行的腳本和一些系統必備代碼,一般移植出了問題不能開機就是這里的問題,一般我們用702的或者720的ROM 里的,注意除了NETD需要用701的外,其他也可以直接用702或者720ROM的,不過一般系統升級不會修改這里,在移植的時候,要刪除2nd- init以及所有.sh腳本文件,這些對701是沒有效果的,如果電池顯示?,那么可以通過替換battd文件來修複)
Etc文件夾(本文件夾里存放著這種配置文件,包括WIFI,藍牙和基帶{\etc\motorola\bp_nvm_default}配置文件,A- GPS的文件和Hosts文件也在這里,media_profiles.xml可以控制錄像質量,cameraCalFileDef5M.bin與 cameraCalFileDef8M.bin是照相的數據庫文件,都可以修改,子文件夾init.d文件夾下可以寫入自己的開機腳本,來實現一些程序或 者腳本開機啓動,如果想要執行某模塊,可以添加一個文件,不要有后綴名,格式爲00aaa  00是執行序號,系統開機時會按順序執行,aaa是爲了區別 每個腳本的名稱,可以隨便寫)
Font文件夾(字體文件夾,沒什么好解釋的,你可以替換爲你喜歡的字體)
Framework文件夾(系統框架結構文件目錄,這個目錄下是系統服務和系統界面的所在地,一般不可以單獨替換,要移植的話必須全部替換,不然會卡 M,framework-res.apk文件就是系統語言,界面的所在文件,修改他就可以直接修改系統界面,framework-res.apk必須與 app文件夾中systemui.apk配套,不然開機會出現狀態欄FC,不同版本不可以亂用,比如CM7.1.0.5不能用CM7.1.0.4的文件)
Lib文件夾(本文件夾是系統所需要用到的驅動,庫文件的所在,如果某程序FC或者無法正常運轉,可能是這里的問題,我把我知道的一些文件的用途說一下:
***Lib/dsp文件夾 DSP驅動所在,一般不需要改
***lib/egl 顯示芯片驅動,一般不需要改
***libaudio.so 話筒及音頻驅動 必須用701的
***libaudioflinger.so 音頻附屬驅動 必須用701的
***libbridge.so 相機方面
***libbattd.so  電池驅動
***libcamera.so 相機驅動 必須用701的
***libcameraservice.so 相機服務驅動
***libfmradio.so FM驅動
***libHPImgApi.so 圖片接口驅動 必須用701的
***libLCML.so 未知驅動  必須用701的
***liboemcamera.so 相機驅動  必須用701的
***libOMX.TI.JPEG.Encoder.so 照片編碼器  必須用701的 否則照片黑
***libOMX.TI.AAC.decode.so  此類型的都是編碼器和解碼器驅動(多媒體)
除上述紅色文件必須用701外,其他文件可以直接用702或者720的。
Media文件夾(鈴聲及開機動畫)
TTS文件夾(文字轉語音文件夾)
Usr文件夾(鍵盤文件與各類數據庫)
Xbin文件夾(系統工具文件夾)
Build.prop文件(系統參數文件,修改這里可以調節系統部分參數與性能)
如:默認虛擬機大小,鈴聲延遲,系統版本等
posted @ 2013-02-17 14:48 小果子 閱讀(468) | 評論 (0)編輯 收藏

在項目中,我們經常要實現以下編輯器的所見所得效果,當然也要支持回車,在此做下記錄,對正則表達式還不是很熟練。

將HTML換行標簽替換為文本域換行符:
textereaContext = divHTML.replace(/(<br>)/g, “\r\n”);

將文本域換行符替換為HTML換行標簽:
divHTML =  textereaContext .replace(/\n|\r|(\r\n)|(\u0085)|(\u2028)|(\u2029)/g, “<br>”);
posted @ 2013-02-04 15:41 小果子 閱讀(4215) | 評論 (2)編輯 收藏

在PHP中查找中文字符,有兩種方案。

1、中文字符是gbk(gb2312)

有兩種解決方法

第一種:

將PHP保存為ASCII編碼,然后使用strpos查找,如:

strpos($curl_res, ‘哈哈’)

第二種:

將PHP保存為UTF-8無BOM編碼,然后轉換字符串編碼為UTF-8,再查找,如:

$curl_res = mb_convert_encoding($curl_res, ‘utf-8′, ‘gbk’);

mb_strpos($curl_res, ‘哈哈’);

2、中文字符是UTF-8

有兩種解決方法

第一種:

將PHP保存為UTF-8無BOM編碼,然后使用strpos查找,如:

strpos($curl_res, ‘哈哈’)

第二種:

將PHP保存為ASCII編碼,然后轉換字符串編碼為gbk,再查找,如:

$curl_res = mb_convert_encoding($curl_res, ‘gbk’, ‘utf-8′);

mb_strpos($curl_res, ‘哈哈’);

應該可以看出一些規律,就是:函數中的中文字符串參數的編碼和PHP文件保存格式的編碼一致,在使用函數時要考慮到!


     我生成的那個html文件被EmEditor認為UTF-8 with Signature。而好用的那個html文件被EmEditor認為UTF-8 without Signature.
    對于這兩種UTF-8格式的轉換,我查看了網上信息,點擊記事本,EmEditor等文本編輯器的另存為,當選擇了UTF-8的編碼格式時,Add a Unicode Signature(BOM)這個選項被激活,只要選擇上,我的文件就可以存為UTF-8 with Signature的格式。可是,問題就在于,我用java怎么讓我的文件直接生成為 UTF-8 with Signature的格式。
    開始上google搜索UTF-8 with Signature,BOM,Add a Unicode Signature等關鍵字。
http://www.unicode.org/unicode/faq/utf_bom.html#BOM
我大致了解了他們兩個的區別。
Q: What is a BOM?

A: A byte order mark (BOM) consists of the character code U+FEFF at the beginning of a data stream, where it can be used as a signature defining the byte order and encoding form, primarily of unmarked plaintext files. Under some higher level protocols, use of a BOM may be mandatory (or prohibited) in the Unicode data stream defined in that protocol.
http://mindprod.com/jgloss/bom.html
BOM
Byte Order Marks are special characters at the beginning of a Unicode file to indicate whether it is big or little endian, in other words does the high or low order byte come first. These codes also tell whether the encoding is 8, 16 or 32 bit. You can recognise Unicode files by their starting byte order marks, and by the way Unicode-16 files are half zeroes and Unicode-32 files are three-quarters zeros. Unicode Endian Markers
Byte-order mark Description
EF BB BF UTF-8
FF FE UTF-16 aka UCS-2, little endian
FE FF UTF-16 aka UCS-2, big endian
00 00 FF FE UTF-32 aka UCS-4, little endian.
00 00 FE FF UTF-32 aka UCS-4, big-endian.
There are also variants of these encodings that have an implied endian marker.
Unfortunately, often applications, even Javac.exe, choke on these byte order marks. Java Readers don't automatically filter them out. There is not much you can do but manually remove them.


http://cache.baidu.com/c?word=java%2Cbom&url=http%3A//tgdem530%2Eblogchina%2Ecom/&b=0&a=1&user=baidu
c、UTF的字節序和BOM
UTF-8以字節為編碼單元,沒有字節序的問題。UTF-16以兩個字節為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字節序。 例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節流“594E”,那么這是 “奎”還是“乙”?

Unicode規范中推薦的標記字節順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:

在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。

這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。

UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。

Windows就是使用BOM來標記文本文件的編碼方式的。


原來BOM是在文件的開始加了幾個字節作為標記。有了這個標記,一些協議和系統才能識別。好,看看怎么加上這寫字節。
終于在這里找到了
http://mindprod.com/jgloss/encoding.html 
UTF-8 
8-bit encoded Unicode. neé UTF8. Optional marker on front of file: EF BB BF for reading. Unfortunately, OutputStreamWriter does not automatically insert the marker on writing. Notepad can't read the file without this marker. Now the question is, how do you get that marker in there? You can't just emit the bytes EF BB BF since they will be encoded and changed. However, the solution is quite simple. prw.write( '\ufeff' ); at the head of the file. This will be encoded as EF BB BF.
DataOutputStreams have a binary length count in front of each string. Endianness does not apply to 8-bit encodings. Java DataOutputStream and ObjectOutputStream uses a slight variant of kosher UTF-8. To aid with compatibility with C in JNI, the null byte '\u0000' is encoded in 2-byte format rather than 1-byte, so that the encoded strings never have embedded nulls. Only the 1-byte, 2-byte, and 3-byte formats are used. Supplementary characters, (above 0xffff), are represented in the form of surrogate pairs (a pair of encoded 16 bit characters in a special range), rather than directly encoding the character.
 
prw.write( '\ufeff' );就是這個。
于是我的代碼變為:
public void htmlWrite(String charsetName) {
        try {
            out = new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(outFileName), "UTF-8"));
            out.write('\ufeff');
            out.write(res);
            out.flush();

            if (out != null) {
                out.close();
            }
        } catch (Exception e) {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e1) {
                System.out.print("write errors!" + e);
            }

            System.out.print("write errors!" + e);
        }
    }
問題解決。

posted @ 2013-02-04 15:38 小果子 閱讀(2965) | 評論 (0)編輯 收藏
僅列出標題
共58頁: First 2 3 4 5 6 7 8 9 10 Last 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久亚洲调教| 欧美色图天堂网| 加勒比av一区二区| 久久永久免费| 美女图片一区二区| 亚洲精品黄网在线观看| 亚洲免费精品| 国产精品色网| 久久亚洲综合色| 欧美激情一二三区| 亚洲欧美久久| 久久久青草婷婷精品综合日韩| 亚洲成人在线网| 99在线精品观看| 国产欧美日韩精品在线| 久久一日本道色综合久久| 欧美高清成人| 欧美一区二区三区视频在线观看 | 毛片精品免费在线观看| 欧美mv日韩mv国产网站app| av成人手机在线| 欧美一区二区免费| 日韩一级精品| 久久成人精品无人区| 日韩天堂在线视频| 欧美一区二区大片| 99精品欧美| 欧美一区免费| 国产精品99久久久久久白浆小说| 欧美一区二区三区在线视频 | 国产午夜亚洲精品羞羞网站 | 午夜天堂精品久久久久| 久久综合激情| 午夜视频一区二区| 欧美久久久久免费| 久久久久天天天天| 国产精品成人aaaaa网站| 免费在线成人| 国产日韩精品一区观看 | 欧美在线视频免费观看| 欧美a级在线| 久久久久久久999精品视频| 欧美日韩高清在线播放| 男人天堂欧美日韩| 国产欧美日韩另类一区| 一本大道久久a久久精二百| 在线观看国产精品网站| 欧美一区二区播放| 午夜视频在线观看一区二区| 欧美日韩国产美女| 亚洲欧洲精品一区二区三区波多野1战4| 国产精品videosex极品| 亚洲精品乱码久久久久| 91久久精品一区二区别| 久久久久久亚洲精品中文字幕| 欧美诱惑福利视频| 国产精品视频免费| 亚洲主播在线播放| 欧美亚洲一级| 国产精品一区毛片| 西西人体一区二区| 欧美一级专区| 国产性猛交xxxx免费看久久| 亚洲欧美日韩在线不卡| 欧美一区午夜精品| 国产视频精品va久久久久久| 亚洲综合999| 久久狠狠亚洲综合| 国产一区二区三区在线观看免费视频 | 亚洲图片在线| 国产精品进线69影院| 中文亚洲欧美| 久久成人精品无人区| 国产农村妇女精品一二区| 亚洲欧美日韩国产中文| 久久精品导航| 亚洲高清一区二区三区| 欧美大学生性色视频| 亚洲精品久久久久久久久久久久久 | 国产农村妇女毛片精品久久麻豆| 亚洲免费在线观看| 久久九九久久九九| 在线观看一区二区精品视频| 欧美搞黄网站| 亚洲婷婷综合色高清在线| 久久精品亚洲精品| 亚洲国产成人高清精品| 欧美日韩 国产精品| 亚洲午夜精品一区二区| 久久天天躁夜夜躁狠狠躁2022| 亚洲国产精品一区二区三区| 欧美日韩黄色大片| 午夜精品久久久久久久99水蜜桃| 麻豆成人在线播放| 亚洲婷婷在线| 激情综合色丁香一区二区| 欧美精品 日韩| 午夜日韩电影| 亚洲国产精品尤物yw在线观看| 亚洲永久免费| 亚洲国产欧美国产综合一区| 欧美视频中文字幕在线| 久久久久久97三级| 日韩一级大片在线| 免费不卡亚洲欧美| 午夜精品久久久久久久99水蜜桃| 亚洲高清资源综合久久精品| 国产精品va在线| 久久中文欧美| 午夜国产精品影院在线观看| 亚洲国产成人精品久久| 久久高清免费观看| 亚洲视频一二| 亚洲国内在线| 加勒比av一区二区| 国产精品免费一区二区三区观看| 牛人盗摄一区二区三区视频| 欧美在线free| 亚洲视频在线观看免费| 91久久精品一区二区别| 久久午夜色播影院免费高清| 午夜精品福利一区二区蜜股av| 亚洲精品欧美日韩| 在线日韩一区二区| 国产亚洲在线| 国产精一区二区三区| 欧美吻胸吃奶大尺度电影| 欧美高清视频一区| 免费亚洲电影在线| 久久久久天天天天| 久久精品国产久精国产一老狼 | 一区二区三区国产盗摄| 亚洲国产精品欧美一二99| 久久偷窥视频| 久久在线播放| 久久综合色影院| 久久综合电影| 久久午夜影视| 老司机aⅴ在线精品导航| 久久久精彩视频| 久久这里只精品最新地址| 久久久www成人免费毛片麻豆| 香港久久久电影| 欧美影视一区| 久久久久国产精品一区| 久久免费99精品久久久久久| 久久精品国产亚洲一区二区三区| 欧美一区二区三区四区在线观看地址 | 亚洲欧美日韩一区二区三区在线| 中文欧美字幕免费| 亚洲一区日韩| 欧美一区二区在线播放| 久久精品一本久久99精品| 久久婷婷国产综合国色天香| 麻豆精品91| 亚洲人成在线播放网站岛国| 亚洲精品看片| 亚洲一区二区三区精品视频| 午夜视频一区| 久久欧美肥婆一二区| 欧美国产欧美亚州国产日韩mv天天看完整| 免费看精品久久片| 欧美色图首页| 韩国av一区| 亚洲免费成人av| 午夜精品一区二区三区在线视 | 欧美在线一二三区| 噜噜噜久久亚洲精品国产品小说| 欧美国产成人在线| 99综合视频| 久久本道综合色狠狠五月| 久久日韩精品| 欧美日韩亚洲高清| 韩日欧美一区| 中国亚洲黄色| 麻豆成人小视频| 一区二区三欧美| 久久人人精品| 国产精品高潮视频| 亚洲大片av| 欧美夜福利tv在线| 亚洲国产高清自拍| 亚洲欧美日韩中文在线制服| 欧美mv日韩mv国产网站app| 国产精品国码视频| 亚洲激情女人| 久久精品国产综合| 妖精视频成人观看www| 久久av一区| 国产精品久久久久久久久免费樱桃 | 欧美一区二区三区免费观看视频| 欧美风情在线观看| 黄色国产精品| 欧美在线播放高清精品| 91久久精品国产91性色| 久久久国产精品亚洲一区| 国产精品国产a级| 日韩视频在线一区二区三区| 免费成人av资源网| 午夜精品免费在线|