2019年4月6日 星期六

android:supportsRtl 屬性在 Android 4.2 影響 PreferenceCategory left padding

markdown Android 踩坑又一發,最近在寫 app 時將原本的 PreferenceFragment 改為 PreferenceFragmentCompat,並且照[之前](http://lausai360.blogspot.com/2018/01/android-support-library-preference.html)介紹過的方式套用 material style,但改完後發現在 Android 4.2 上面 PreferenceCategory 的 left padding 為 0,跟其他的 preference 不對齊。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFxc5DYrhLrxNliVBe-IIKyU0oDhJbP7YDvvC5-NQaO_z_IdMgr4iuNb8csBCqzPapOPcXtUpe_r-IdInkfI7C0PlAYGv0kaHLKR62tWS-zgmlechU_HqrE3TWHvXXjqCpSuWLEH_e216S/s1600/Image+7.png) 網路上不管怎麼搜尋,有關 left padding 的問題都是在問 support library 28 中 left padding 過大,從沒有 left padding 過小的問題,花了一天多都沒有找到原因。契而不捨的追查,血都吐了幾升,最後才發現 app 將 android:supportsRtl 設為 true 後,PreferenceCategory left padding 就恢復正常了。 android:supportsRtl 這個屬性只是影響你的 app 能不能從右到左布局,跟 Preference 根本沒有關連,怎麼都不會聯想到這個屬性會造成 Preference 布局異常。 後來用 android:supportsRtl keyword 去搜尋,也沒有找到任何跟 Preference 布局有關的討論,只能說自己太衰,踩到這個可能沒人踩過的坑。

2019年4月5日 星期五

Android allowBackup 設定

markdown 原本以為 Android app 移除後所有的資料包含 shared preference 都會被移除,但在測試 app 的時候發現,移除 app 再重新安裝後,之前儲存的 shared preference 被 reload 回來了。研究後發現這是因為 Android 會自動把 app 的資料備份出來,就算 app 被移除,備份的資料還在,當 app 重新安裝時就可以把舊資料覆蓋回來。 Android 還提供了一個 [allowBackup](https://developer.android.com/guide/topics/manifest/application-element#allowbackup) 的欄位可以讓開發者設定這個備份行為要不要打開,因為有時候也許開發者就是希望這個 app 重裝後要讓 shared preference 是初始狀態,不過這個欄位預設是 true。 後來 allowBackup 也被人提出有安全風險,因為如果這個欄位被設為 true 了,除了 Android 會自動備份之外,使用者也可以透過 adb 將 app 的 shared preference 備份出來,然後再還原到另一個機器上同樣的 app 內,這有可能會有資料洩漏的疑慮。所以在開發 app 時要注意到底要不要允許 allowBackup。

電錶的幾位半是甚麼意思

markdown 電表常常聽到四位半、五位半、六位半等等術語,這個幾位半是表示電表可以顯示的最大位數,例如三位半表示三個全位元加一個半位元的最高位,全位元是表示可以顯示 0 ~ 9 所有數字,半位元通常只能顯示 1,所以三位半的電表,若設定量程為 20v,則能顯示的最大電壓為 19.99 伏特。 因為半位元理論上要能顯示 2,但只能顯示 1,理論值為分母,實際最大值為分子,就叫 1/2 位也就是半位元。 事實上還有 2/3 位、4/5 位等等不同規格的最高位元,只是如果是統稱的話都可以叫做半位元,而每個電表的那個半位元理論值跟實際最大值多少,還是要看電表的手冊才能確定。

Android 當螢幕旋轉時保持 UI 狀態

markdown Android 的 activity 在螢幕旋轉時會被 destroy 然後再重新 create,這樣設計的用意是讓 activity 可以為不同螢幕方向套用不同的 layout,不過這樣會造成一個問題,就是 activity 重新 create 了,UI 也回復到初始狀態,想像一下如果在 UI 中有一個可以動態增加的 list,使用者只不過螢幕轉向了 list 就被清空,這應該是無法接受的。 在面對螢幕轉向的問題時,要嘛就是在 app 中限制螢幕方向不讓轉向,要嘛就是想辦法在螢幕轉向時保存 UI 資料。 螢幕轉向這種情況在 Android 中有專門的術語叫做 configuration change,螢幕轉向只是 configuration change 的其中一種,還有其他不同狀況的 configuration change 例如系統語言切換,Android 已經有提供兩個 callback function ,讓我們在 configuration change 時保存與回復資料。 * [onSaveInstanceState](https://developer.android.com/reference/android/app/Activity.html?hl=zh-tw#onSaveInstanceState(android.os.Bundle)) * [onRestoreInstanceState](https://developer.android.com/reference/android/app/Activity.html?hl=zh-tw#onRestoreInstanceState(android.os.Bundle)) 這兩個 callback function 是 activity life cycle 的其中一環,在 activity 因螢幕轉向被 destroy 和 recreate 的過程中會呼叫這兩個 callback function,開發者趁此機會把一些該存的資料保存起來。 不過這個方式有些問題,就是被保存的資料是寫入到 disk 中的,而這兩個 callback function 又是在 main thread 中執行的,若是小量單純的資料還好,但若是複雜的資料就不適合了,可能會讓 app 感覺 lag,使用者體驗變差。而且如果每次螢幕轉向資料都要寫入到 disk 一次,想想也覺得挺蠢的。 對這個問題,網上有人提出用一個 fragment 來保存這些資料,並且呼叫 Fragment.setRetainInstance(true) 讓 fragment 可以在螢幕轉向時不要被 recreate。這個方法不錯,而後在 2017 Google IO 大會上,Google 提出了一系列新的組件,其中有一個叫做 ViewModel 的組件,就是用來解決這個問題,其背後的原理,就是在內部用了一個 Fragment 並且設定 RetainInstance 為 true。 下面的圖很清楚的表達了 ViewModel 的 life cycle,除非 activity 被 finish 了,不然不管你怎麼重建,ViewModel 都還是在記憶體中活得好好的。至此,ViewModel 成為了處理螢幕轉向問題的最佳解法。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0UrVMhkC_dQPGvD_0DiCoQtQwOQ7YWDWzLOG8FVPI8TsQ1zw8q9d3e_brMrGgSPr_Mnc0SimTw8vvVpdhmJPvwHuv3QG-cb4ymkps2fxq6vrugZZYm5USO_emhW8VBRiUpCbQza8yctJq/s1600/1+3Kr2-5HE0TLZ4eqq8UQCkQ.png) 但 ViewModel 的出現並不是要取代之前的 onSaveInstanceState、onRestoreInstanceState callback function,onSaveInstanceState 會在系統因一些資源匱乏的原因殺死你的 app 前呼叫,不只是在螢幕轉向時呼叫而已,將一些重要的資料保存在 disk 還是有必要的。所以還是應該視需求來決定用何種方式來保存你的 UI 資料。 Reference: * [The Real Best Practices to Save/Restore Activity's and Fragment's state. (StatedFragment is now deprecated)](https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en) * [ViewModels : A Simple Example](https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e) * [ViewModels: Persistence, onSaveInstanceState(), Restoring UI State and Loaders](https://medium.com/androiddevelopers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090)

2019年4月2日 星期二

Intermodulation Distortion 三階互調失真

markdown IMD (Intermodulation Distortion),中文叫做互調失真,是分析 RF 性能的一個指標。它的由來是當 RF 訊號經過 power amplifier 之後造成的各階諧波雜訊與原訊號交互生成產生。 在理想的 power amplifier 中,一個在 F1 頻率的訊號進入,其輸出訊號應該只有在 F1 頻率上然後功率增強過的訊號,但是現實中的 power amplifier 會在 F1 的整數倍頻率,例如會在 2F1、3F1……等頻率產生諧波。 假如今天輸入訊號是兩個 RF 訊號 F1 跟 F2,情況就變得更複雜了,除了會產生 2F1,2F2 等諧波,還會產生 second order distortion product、third order distortion product,所謂 second order distortion product 就是在一階諧波頻率相加減的頻率處,也就是在 F1 + F2 和 F2 - F1 (假設 F2 > F1) 處產生的雜訊。third order distortion product 就是在一階諧波頻率與二階諧波頻率相加減的頻率處產生的雜訊,可見下圖。當然還有三階跟四階乃至於無限階的 distortion product。但那些不會是關注的重點,一般來說關注的只有 third order distortion product,因為它的頻率最接近原始輸入訊號,很容易影響訊號品質。 ![三階互調失真](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtn863tETzUScNS5C9DZhaOt163jD_1kic6pRZIi2ujPEKrupntn9el1eMRCvsL91WSGKwuVvT2tkaoYvnKtMeKFm0fFDTV1V5xzKPa-TCA6kVL1dFn_XyCb6btxnV8ipTyhloj2vCMfsx/s1600/1107_MakingWaves_F1.gif) Intermodulation distortion product 還有個特性是訊號強度增加的速度是 power amplifier 輸出原始訊號強度的三倍,也就是原訊號假如增強 1db,那 intermodulation distortion product 就會增加 3db,所以理論上在原始訊號達到某個強度的時候,third order distortion product 會跟原始輸出訊號強度一樣強,而這此時的訊號強度就稱為 TOI(Third-Order Intercept) 雖然理論上 third order distortion product 有可能跟原始輸出訊號一樣強,但是這個值通常會非常大,所以一般來說都是計算得出,而不是真正量測到。TOI 的計算可以參考下圖,假設 IP 為原始訊號強度與 intermodulation distortion product 強度 Pout的差,則 TOI 的公式如下 TOI = Pout + |IP/2| ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJR3F60dt2hNeNJ-kZiy_t93naObsM0v8a8xY1QeqzZYDBLYe46_IdgRvL7Va4cXdmHx2_dJ5ePQHD9wgDfMRm4z-4A6ujBWo2-geYAcBRjtKc6dSXpP303ED5XKtWjPirW9ThpM1kPkQT/s1600/Image+2.png) Reference: * [Intermodulation Distortion Measurements](https://www.electronicdesign.com/communications/understanding-intermodulation-distortion-measurements) * [Intermodulation Performance and Measurement of Intermodulation Components](http://users.tpg.com.au/users/ldbutler/Intermodulation.htm) * [Understanding Radio Frequency Distortion](https://www.dsprelated.com/showarticle/108.php) * [Intermodulation Distortion(IMD) Measurements](https://www.electrotest.co.nz/site/etl/Papers/Intermod_Measurements.pdf)