2021年5月29日 星期六

[Android] SharedPreferences string set 的坑

markdown 之前曾經遇過一個問題就是用 SharedPreferences 儲存 string set,我已經呼叫完 commit,但是 app 關掉重開之後,卻發現 string set 卻沒有寫入到,當時一直沒搞清楚是甚麼問題,最近偶然看到原來用 string set 有這樣一個坑,值得在這裡紀錄一下。 當時一直在想是 putStringSet 出了甚麼問題,但問題是出在 getStringSet return 的 string set,不能直接將資料加到這個 string set 傳給 putStringSet,因為 putStringSet 會比較傳進來的 string set 與 getStringSet return 的是不是同一個 object,如果是則不做任何動作。 這可能是為了效能考量,但其實挺違反直覺的,不注意真的很容易踩坑。 --- * [Misbehavior when trying to store a string set using SharedPreferences](https://stackoverflow.com/questions/14034803/misbehavior-when-trying-to-store-a-string-set-using-sharedpreferences/14034804#14034804) * [Android: String set preference is not persistent](https://stackoverflow.com/questions/16820252/android-string-set-preference-is-not-persistent) * [What's the difference between commit() and apply() in SharedPreferences](https://stackoverflow.com/questions/5960678/whats-the-difference-between-commit-and-apply-in-sharedpreferences)

2021年5月23日 星期日

windows git bash 遇到 cp950 顯示亂碼問題

markdown 最近在 windows git bash 遇到執行程式時中文顯示亂碼的問題,但是在 windows cmd.exe 卻可以正常顯示,例如下圖用 ping 指令,當用 Ctrl-C 結束執行時,windows git bash 顯示亂碼。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4BBDug-9QU5ilYgv9mQOxVUZhjQFlcE1aXXc_Rix-vaBx308E58Bkza47ds_1dDrn9R4HfOqqCyBwq9JGFAz3tbkXUaEXoTAgxGdfcvv1bYu1gviwjs-dbDX0oyn4kDnU4G3HkfKHk-EB/s0/Image+5.png) 為什麼會這樣,可以先來做一個實驗,將下面的程式用 cp950 的編碼儲存為 a.cpp 檔案。
#include <cstdio>

int main()
{
    printf("中文");
    return 0;
}
然後我們用 cl.exe 編譯這個程式,如果檔案編碼的確是用 cp950 儲存,編譯器不會有警告,反之則會有警告。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfppplz29Cxky6GlJfubmV7rbjNS90zgj3anew2QE6-NysjEYjFd3tblvrPK7K6frlHLrpxy4V4jqfups68AH4N3wfSokhnJQyu1OwdzHqKmtLX4kCnVh4ylp5_yNbudnpzyFzLepE0NVa/s0/cl.png) 然後在 windows cmd.exe 跟 windows git bash 中執行編譯好的執行檔,會發現跟上面的 ping 指令一樣,windows cmd.exe 正常,windows git bash 亂碼。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSpe-AT_rfBU1yRxw-xxGGSyD1WKSMBarWo4zZ_OGy7ldwwil0fyVSHQHRcGhVdX5uL9hFOwGYstt5pH2cnbasposH_NnN2t7621zpy2lKeLS0XGRTsHdznN8kZT9J3J3c8KQIpO1UlM4X/s0/Image+7.png) 究其原因,是因為 windows git bash 預設是使用 utf-8 編碼,當它遇到 cp950 編碼的中文,不知道怎麼顯示,於是就變亂碼,而 cmd.exe 預設就是 cp950,所以可以正確顯示。 windows 一些老舊的內建程式還在使用 cp950 輸出文字,例如上面的 ping 指令,如果每次要用到這些指令就要切到 cmd.exe,實在太麻煩了,不過還好 windows git bash 內建的一個工具 winpty 可以很好的解決這個問題。 [官網](https://github.com/rprichard/winpty)上對 winpty 的描述如下。
winpty is a Windows software package providing an interface similar to a Unix pty-master for communicating with Windows console programs. The package consists of a library (libwinpty) and a tool for Cygwin and MSYS for running Windows console programs in a Cygwin/MSYS pty.
可以看到,其實 winpty 的本職工作是在 windows 上做一個類似 linux 虛擬終端的,只是剛好它有將 cp950 轉為 utf-8 輸出的功能而已。關於虛擬終端是甚麼,超過這裡討論的範圍,想了解的可以看[網上這篇](https://zhuanlan.zhihu.com/p/61369678)有詳細的講解,不想了解的也沒關係,只要知道它能幫我們解決windows git bash 遇到 cp950 的亂碼問題就好。 使用方法只要將指令放在 winpty 後面就可以,如下圖所示,可以看到用 winpty 之後 ping 指令就可以正常顯示中文了。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrYreGQWBEPNV205YaaPCWnq9WQHzaeyH_jP5IrQ_GoaS5524_6-mHBNV0FePtLXEFGb2FVYvGMt-A_f6zOfe5gz2Iyvk5ywJR90SVkmxMAFX0uiAelU6xX8QVFjI3FpRWU3CF3k_sqnHG/s0/Image+4.png) --- * [winpty github](https://github.com/rprichard/winpty) * [Cygwin系列(十一):折騰終端2](https://zhuanlan.zhihu.com/p/102393122) * [Linux Cygwin知识库(一):一文搞清控制台、终端、shell概念](https://zhuanlan.zhihu.com/p/61369678)

2021年5月15日 星期六

Firefox 的開發者工具

markdown 最近有個爬網站的需求,就花了點時間研究一下有甚麼工具能幫助來 trace 網頁,發現 firefox 內建的開發者工具就是一個很好用的 tool,現在最常用到開發者工具兩個主要功能,來稍微介紹一下 一個是查看 html 的 DOM 結構,這裡查看的 DOM 結構不是單純看網頁原始碼可以看出來的,因為現在的網頁很多都是後來再用 javascript 處理過資料再呈現出來,開發者工具的 [Page Inspector](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector) 可以讓你查看經過 javascript 處理過後實際呈現在使用者眼前的 DOM Tree 還有各種 DOM 節點內的屬性。 第二個是用開發者工具的 [JavaScript Debugger](https://developer.mozilla.org/en-US/docs/Tools/Debugger) 來 trace 網頁中的 javascript。裡面有一些好用的功能例如將 minify 過的 javascript 重新排版,或是設定 breakpoint,也可以單步執行。 這兩個功能對 trace 網頁內容幫助很大,但是現在的網頁有很多其他厲害的方法去防止你爬它們網站,例如每次自動生成變數跟函數名不同的 javascript 檔案,讓你就算可以 trace,或是要寫程式去爬時也要花非常非常大的時間與精力,這個可能就只能靠經驗與熟練度來克服了。