最近遇到一個問題,就是本來是彩色的圖標,結果在5.x的設備商status bar上面notification icon的顏色是黑白的,而在4.x上面是彩色的。
在SO上面找到這篇文章,http://stackoverflow.com/questions/28387602/notification-bar-icon-turns-white-in-android-5-lollipop。大意就是這個是5.x(api 21)的新行為,如果AndroidManfifext.XML中的android:targetSdkVersion設置為21,那么在5.x的系統上,就是這種行為。如果一定要顯示彩色,像4.x那樣,就設置android:targetSdkVersion為老的api號,例如20。
正好研究了下targetSdkVersion生效的機制。對於這個例子而言,可以參看BaseStatusBar的實現代碼:
if (entry.targetSdk >= Build.VERSION_CODES.LOLLIPOP) { entry.icon.setColorFilter(mContext.getResources().getColor(android.R.color.white)); } else { entry.icon.setColorFilter(null); }
他會根據entry.targetSdk判斷是否使用黑白模式。
這里的targetSdk就是在android:targetSdkVersion。如果看這段代碼的調用關系,就會發現entry.targetSdk的值是通過:
ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
entry.targetSdk = info.targetSdkVersion;
賦值的,即ApplicaitonInfo.targetSdkVersion。
所以如果是在5.x的系統(sdk version是21/22)上運行應用,如果指定了targetsdkversion為21/22,那就會生效黑白模式;如果指定了targetSdkVersion為20或更低的值,則這段新的原色過濾的邏輯不生效,還是使用原有系統的行為。於是如果我們想在新的系統上仍然讓應用保持舊系統的行文,就可以通過設置該屬性為舊api版本來實現。
如果設置了targetSdkVersion為21,但運行在舊的4.x系統上(例如api 19),那因為實際的sdk runtime根本沒有處理這么高targetSdkVersion的代碼,所以自然也不會生效。而且sdk的代碼一般采用>=某個版本號的方式來判斷,所以保證了寫21和寫19的效果在19的機器上是完全一樣的。
