編輯:關於Android編程
今年3月,Google 破天荒提前半年發布了 Android N 開發者預覽版。當然,作為一個不合格的谷粉並沒有第一時間體驗安裝,因為至今仍然能夠回憶起來去年今日此門中(霧)興沖沖刷了 Android M Preview 的時候發現各種 crash 就連微信也(不出所料得)中招時自己一臉懵逼的心情。當然,為自己的機智而慶幸並沒有過多久,很快就有微信好友(當然也是純純的谷粉)反饋微信又雙叒叕在 Android 新版本下 crash了……好吧這次我們的時間很充裕,因為5個 preview 之後才會發布最終 release 版本。令人失望(咦)的是,我們的工程師在一天之內就修復了這個 bug 並且趕在當天6.3.15alpha 版本發布之前修復並合入主線,辜負了 Google 的一片苦心。
痛定思痛,當天我就拎起來麒麟臂,在 chrome 的地址欄重重得敲入:http://developer.android.com/preview/overview.html(復制鏈接到浏覽器裡打開),並且聽說 Google 在北京舉辦了 Android 開發者大會的時候,屁顛屁顛得過去了。
在這個『人人都是產品經理』的年代,作為程序員當然是敲得起代碼,當得起經理(。。。)。如果我是產品經理,Android N 的更新無非是以下三個點:
默認多窗口支持強化通知,裡邊有你最喜歡的直接回復沒了…當然不是:Android Developer一筆帶過的重磅feature:允許第三方應用在快速設置中添加自己的服務注意『默認』二字:這很重要,這很重要,這很重要。
Android M 裡邊,系統允許應用在啟動某 Activity(對於 PM 來說可以不嚴謹得理解成界面)時帶上特殊參數,該應用可以在最近任務窗口中和主應用分開顯示,即 multi-tasking 支持。當然,並沒有多少應用鳥這個 Android M 中為數不多的新特性之一,因為效果實在是不明顯。也有一定的原因是在這個大部分產品經理不會關注 Android DevelZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcGVyILXExOq0+qOs1eK49rfHxKzIz7XEzNjQ1Mq11Nqyu7vh0v3G8Mv7w8e1xNei0uKhozwvcD4NCjxwPtTaIEFuZHJvaWQgTiDW0KOsvrnIu9axvdPWp7PWwcsgbXVsdGktd2luZG93o6HL5Mi71eK49szY0NSyorK7vqrR3qOs1NogaU9TILrNyP3Qx7XEu/rQzdbQ1OfS0dans9ajrMn11sHU2iBBbmRyb2lkIE0g1tCjrNKyv8nS1NSkwvHBy9XiuPbM2NDUo6yyor/J0tTNqLn9xLPQqczYyuK3vbeov6rG9KGjyLu2+KOsus0gaU9TINOm08PQ6NKqzNjK4sn5w/eyxcTc1qez1rbgtLC/2rXEzNjQ1LK7zayjrEFuZHJvaWQgTr65yLvErMjP1qez1sHLtuC0sL/aoaPV4tLizrbXxcjOus7Su7j206bTw6Oszt7C2yB0YXJnZXQtYXBpIMrHt/HKxyBBbmRyb2lkIE6jrLa81qez1rTT1+69/MjOzvHW0LOksLTTptPDserM4sC4vfjI67bgtLC/2sSjyr2ho9XiwO/Kx7j2IGRlbW+hozwvcD4NCjxwPsSsyM/Wp7PW0rK+zdLizrbXxbP9t8fM2MriyfnD96OsyM66ztOm08O2vNans9bHsMr2ytPGwcv5yr7Qp7n7o6zSsr7NysfLtcjnufvTptPDsrvV67bU1eLW1sSjyr29+NDQzerDwMrKxeSjrLvy1d/LtdPDwcu++LbUsry+1rXEu7CjrMTjtcTTptPDvs274aGjoaOho6Gjuse6x7rHoaM8L3A+DQo8cD61sci7o6zV4tbWwM+19NHAtcTM2NDUyseyu7vh0v3G8LjfwOS1xCBQTSC1xNei0uK1xKOs1ru74cjTuPi/qreiube9u7j4ztLDx8ilysrF5KGjxMe6w7DJo6zAtNK7uPYgb25lIG1vcmUgdGhpbmcgtMy8pNK7z8LE46O6PC9wPg0KPHA+1NogQW5kcm9pZCBOINbQo6y9q9ans9a31sbBx+m/9s/CIGRyYWcgYW5kIGRyb3CjrMjD1eK49jQuML+qyry+zdans9YgZmFldHVyZSC7wLeiwcvQwsn6oaPV4tKyvs3S4s6218XE47/J0tS9q9K7uPbTptPDxNqhosn11sGyu82s06bTw7zktcS31sbBx+m/9r2r0ru49rfWxsHEu7/YvP7Nz9entb3B7c3i0ru49rfWxsHEu6Gj0rLQ7b/J0tTTw8C0zc/Xp828xqy/7MvZt6LNvKOsu/LV36GjoaPL5rHjxOPP67jJyrLDtKGjPC9wPg0KPHA+tbHIu6OstNO/qreiube1xL3HtsjAtMu1o6zV4sDv09DSu7XjsLLIq9L+u7yjusjnufvNqLn9zc/Xp72ryv2+3bSrtd25/cC0o6zE48n11sGyu9aqtcDAtNS0ysfKssO0oaO1q8rHz+vP69KyysejrLHPvrnTw7XEus3Vs8z5sOXSu9H5tcS907/ao6y7ucTc1rjN+8qyw7TE2KO/PC9wPg0KPHA+we3N4qOs1/fOqrfWxsG1xNK71tbM2Mri0M7KvaOsu63W0Luto6hwaWN0dXJlIGluIHBpY3R1cmWjqdKytcO1vcHLz+DTprXE1qez1qGjsru5/b7dIEdvb2dsZSC1xLmks8zKpsu1o6y7rdbQu63Eo8q91vfNxiBBbmRyb2lkIFRWINbQ06bTw6Oo0rLQ7SBHb29nbGUgyM/OqtTaytaz1snosbjJz7OhvrCyu9fjo6mho7K7uf0gd2hhdGV2ZXKjrM/W1Nq63LbguabE3NLRvq2/ydLUzai5/bihtLC907/ayrXP1qGju63W0LutttTT2tf2ytPGtdOm08O78tXf09DK08a11qez1rmmxNy1xNOm08O3x7Oj09Cw79b6oaM8L3A+DQo8cD60y83io6y4+LPM0PLUscXz09HDx7y4uPbQocz5yr88L3A+DQrL5Mi7t9bGwde0zKzPwsG9uPbTptPDtry/ybz7o6y1q8rHttTT2rfHIEZvY3VzINe0zKy1xNOm08O1scewyse0ptPaIG9uU3RvcCDXtMystcSjrNKyvs3Kx8u1o6yyosO709DKtbzK1NrUy9DQ1tCho9Stsb4gb25TdG9wILXEyrG68tOm08PTprjDyseyu7/JvPujrLWrysfP1tTav8m8+8HLoaOho6Gj1K2xvrXE0rvQqbbx0MTC37yt16LS4tDeuMTPwqGjy+TIu7fWxsHXtMysz8K1xNOm08Oyu7vhIGRvdWJsZSDE2rTm1bzTw6OstavKx8TatObVvNPDv8+2qLvhscjV/bOj17TMrLTzo6zXotLit9bGwcSjyr3Pwry0yrHKzbfFxNq05qGjysrF5LrDxOO1xLPM0PKjrLjDvNMgc2Nyb2xsILXEtdi3vbzTIHNjcm9sbKGjtbHIu6OsyOe5+9Stsb61xMTjtcSzzNDyvs3S0b6t1eu21Lbgs9+058bBxLvT0MHLtKbA7aOsvs3S0b6tzerDwMrKxeTBy9XiuPbEo8q9DQo8aDIgaWQ9"強化通知">強化通知
通知欄一直是 Android 引以為豪的方面。相對於 iOS 的通知欄來說, Android 的通知欄具有幾乎完爆的功能:自定義控件,自定義 Action,可以定義下來拓展的控件……除了快速回復。
在這之前,先上一段 Android N 新版本的通知欄和快速設置欄,至於為什麼放視頻,嗯。。。因為我覺得很好看:
http://v.qq.com/page/k/6/m/k0196nl7i6m.html
如今,這一點已經被 Google 迎頭趕上,並且體驗絕不亞於 iOS,甚至好很多。
當然,如果一次來了多條消息並且都不是一個會話中,快速回復也是毫無壓力:
這個新特性簡而言之就是滿足了快速回復的一切需求,也許從此再也不用擔心沉浸式閱讀時需要跳出回復消息這種傷害體驗的情況。
當然了,除了快速回復,還有根據應用歸檔通知,這無疑是一個大殺器:
同時,這裡需要同時提醒PM和開發同學的是:如果真的需要在通知上設置自定義控件,請調用DecoratedCustomViewStyle()。它會讓你的自定義控件在通知欄顯得更加和諧。Sample:
1
2
3
4
5
6 Notification noti = new Notification.Builder()
.setSmallIcon(R.drawable.ic_stat_player)
.setLargeIcon(albumArtBitmap))
.setCustomContentView(contentView);
.setStyle(new Notification.DecoratedCustomViewStyle())
.build();
Quick Setting
說到這個話題,真的很想用標准朋友圈標題:《Android Developer 一定不會告訴你的事!怒轉!》,嗯,希望朋友圈的產品經理和運營們不要打我。
幾乎所有人刷了 Android N 之後最大的感觸只有三個:1. 這特麼和 Android 6.0 有毛區別!2. 通知欄好看了 3. 通知欄拉到一半就會有快捷通知,真是懶人福利。
嗯。。好吧。。。
99%的人不會發現的秘密:Android N 中允許第三方應用程序向快速設置欄添加自己的快速部件。這個可比傳統 Widget 方便快捷得多。當然,這個入口千萬不要做特別重的操作。同時,區別於 iOS 的通知欄部件,你的入口將和 WiFi 開啟、GPS 設置等系統設置同等級。當然,這一切的一切前提是用戶將你的 QuickSetting 部件拖拽到了快捷入口的位置。我寫了一個小sample:
http://v.qq.com/page/o/p/g/o0196ayszpg.html
雖然接口還沒有出現在 Android Developer,但是已經有離線文檔可以下載,裡邊就有 Tile API。
好吧。。。其實我寫了一個小 sample,點擊這裡就可以下崽下載了騷年。
你咋不上天呢!
總之,我已經看到 PM 們揚起的嘴角,並且計劃著如何強奸這個快速設置欄(幸好有需要用戶拖拽設置這一條)。不過還是希望各位維護這個生態啊親們!
其他的一些(PM們可能不會關心的)feature
號碼阻止: 全局的電話號碼黑名單,如果你是做電話相關的應用,可以使用這個 API 進行全局黑名單控制,並且為這個黑名單貢獻自己的一份力量(加油)。允許第三方通化應用自定義 Call Screen:是的,從現在開始再也不用做什麼hack就可以將自己的通話應用徹徹底底得取代系統電話了。更加多元的多語言支持:就像 papi 醬視頻裡的 Sophie,越來越多的中國人已經可以(自以為)熟練得掌握了第二語言、第三語言。Android N 中,用戶可以在系統語言選擇中選擇多種語言,應用程序也可以通過全新 API 獲取用戶使用語言的列表,而非單一語種。直接啟動(Directly Boot):這個名字看上去很碉堡,但是實際上大部分應用可能用不上。實際上就是系統在啟動了但是還在鎖屏狀態時,允許特定聲明的程序快速啟動並訪問加密文件數據。希望不要變成應用搶占運行狀態的一個接口,大家高抬貴手,有點節操。快捷方式強化:以後終於知道自己的 app 有沒有已經設置過某個快捷方式,並且能夠更加方便得管理它們,而不用傻傻得先刪除快捷方式再添加一個。輔助功能強化:今後將會支持輔助功能手勢操作。不過。。。求PM放過這個原本給殘障人士使用的 feature。現在輔助功能都被用來做搶紅包插件了。好了,到這裡為止,對於一部分 PM 來說,這個文章就結束了,可以去准備需求文檔了(去吧,皮卡丘)!
當然,我們非常歡迎熱愛探索的PM們繼續與我們愉♂快♂討♂論♂程序員的世界。
程序員的世界
在這個章節,我不會具體去講剛剛提到的那些 feature 該怎麼實現,幾乎所有的 feature(除了我已經提供的快速設置 API 之外)都有相應的 Sample。
Doze 模式更加強大
Doze 模式是 Android M 中推出的一個省電模式,當手機滅屏一段時間之後(一般而言是十幾甚至幾十分鐘),設備會進入 Doze 模式。在 Doze 模式中,系統會通過減少應用 CPU 調用以及禁止掉網絡連接,達到省電的目的。與此類似還有一種機制叫 App Standby,顧名思義只要你的應用在一段時間內沒有操作並且不在前台,比如主動彈一個 Notification 之類就會把你暫時凍結掉,Standby 嘛,一邊玩去。嗯。。。好像哪裡不太對。
『這不是逼著應用瘋狂彈通知麼!』
所以,Android N中,Doze模式變得更加強大且不容易被突破了。只要手機滅屏一小段時間,並且當前不在充電狀態,就會進入 Doze 模式。在Doze 模式下,你的應用就幾乎可以肯定拿不到 WakeLock,甚至於普通的 AlarmManager 也已經無法使用。
『可是我的應用是一個鬧鐘應用/有定時提醒功能,怎麼辦!』
這種情況倒也好辦,要麼就是讓用戶將自己的的應用加入白名單,要麼就主動申請權限:
An app holding the REQUEST_ IGNORE_ BATTERY_ OPTIMIZATIONS permission can trigger a system dialog to let the user add the app to the whitelist directly, without going to settings. The app fires a ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Intent to trigger the dialog
當然,對於大部分應用來說,影響最大的就是網絡方面。應用滅屏了就不能聯網,IM應用們該怎麼辦!
對此,Google 給了兩個解決辦法:
應用可以通過 PowerManager.isIgnoringBatteryOptimizations(java.lang.String)接口查詢到自己是不是在白名單內,如果不在,則通過ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
這個動作引導用戶進入系統設置添加自己為白名單。應用使用 GCM 服務。即使是 Doze 模式,GCM 依然可以有效運行。但是,中國大陸的 Google 服務。。。你懂得。當然了,根據各種小道消息,這個服務很可能近期會可用。各位可以通過這個鏈接(https://developers.google.com/cloud-messaging/)讓你的應用支持 GCM。畢竟即使 Google 不入華,讓歪果仁們用的時候也要保證你的應用的可用性。
對了,順便安利一個開源的分析工具:耗電記錄。這個也是 Google 官方的耗電分析工具,可以方便得查看系統內耗電占用,甚至某個應用的某個組件耗電。像這樣:
一目了然。
瘦身計劃
這個並不是說 Android 機器人變瘦了,實際上,它還是那個胖胖的樣子:
額。。。天天吃蘋果當然會胖。。。
言歸正傳,實際上,自 Android L 開始,Google 就在強力推薦應用使用 JobScheduler 代替其他方式來進行後台服務,甚至在2014年的 Google I/O 大會上將這個新接口放在了大會上演示,這是其他接口都不曾有的待遇。當時我甚至還在朋友圈聲稱這個將會是以後實現後台服務的唯一方式。
可是現實重重得打了我的臉,這個接口的使用率並不理想。終於,在 Android N 上,Google 重提了這個接口,並進行了大規模的強化。今後,如果有需要後台處理的數據、或者特定情況的後台處理。舉個例子,如果你需要在用戶充電並且不在數據網絡的時候處理一些邏輯,你就可以這樣:
1.public static final int MY_BACKGROUND_JOB = 0;
2....
3.public static void scheduleJob(Context context) {
4. JobScheduler js =
5. (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
6. JobInfo job = new JobInfo.Builder(
7.MY_BACKGROUND_JOB,
8.new ComponentName(context, MyJobService.class))
9. .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
10. .setRequiresCharging(true)
11. .build();
12. js.schedule(job);
13.}
『何必這樣,我寫一個 BroadcastReceiver 監聽 CONNECTIVITY_ACTION 然後處理不就行了,naive!』
科科。
為了防止這個沒有節操的事情發生,Google 在 Android N中拿掉了這三個廣播:
CONNECTIVITY_ACTION:網絡變化ACTION_NEW_PICTURE:添加新圖片ACTION_NEW_VIDEO:添加新視頻這也是我非常佩服 Google 的一個點,敢於做減法。當然,留下的坑就多了,比如 CONNECTIVITY_ ACTION,很多應用(包括微信)都會監聽。今後需要使用 JobScheduler 實現相同的邏輯了。JobScheduler 有非常多的好處,他會根據用戶當前設備的情況,比如當前 RAM、電量、模式、是否應用在前台等等,決定是否執行該邏輯。你也不希望自己的程序變成用戶手機變卡的罪魁禍首,從而讓用戶怒刪,對吧?
當然了,不允許監聽 CONNECTIVITY_ ACTION 針對的是靜態注冊的 BroadcastReceiver,如果是動態注冊的 BroadcastReceiver 則並不會受到影響。
早在前年開始研究 Annotation 的時候,就在感慨為什麼 Android 一直不支持 Java 8,即使現在 Java 9都快出了。終於的終於,Android從N版本開始支持 Java 8的編譯,前提是要在 Gradle 文件中顯式聲明使用 Jack 編譯器。
這個 Jack 是什麼鬼呢?簡單來說,傳統的編譯工具鏈是將 java 代碼通過 javac 編譯成.class 文件,再通過 dx 編譯成.dex。也就是醬紫的:
1.javac (.java --> .class) --> dx (.class --> .dex)
而 Jack 則是一條龍服務,中間不需要經過其他工具或者命令,一條命令就可以將.java 文件編譯成.jack 從而編程.dex:
1.Jack (.java --> .jack --> .dex)
使用 jack 非常簡單,gradle 配置即可
1.android {
2. ...
3. defaultConfig {
4. ...
5. jackOptions {
6. enabled true
7. }
8. }
9. compileOptions {
10. sourceCompatibility JavaVersion.VERSION_1_8
11. targetCompatibility JavaVersion.VERSION_1_8
12. }
13.}
不過,Android N 版本的 Java 8特性並沒有支持全,不過主流的 feature 已經支持,包括:
定義接口默認實現方法Lamda 表達式支持(喜歡語法糖的同學的福利)Repeatable annotations。這個已經可以說的內容很多,改天有空給大家慢慢介紹。Method Reference。這個實話實說我並不是太了解,也是語法糖一種。感興趣的同學可以看看這個鏈接:https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html但是現在還沒有支持一個很重要的特性:Stream。但是現在還在 Preview 階段,比如剛剛的第四條 Method Reference 就是 Preview2 支持的,可以期待下 release 中是否會支持(最新消息:已經支持 java.util.stream 接口,棒棒的!)。
此外還需要注意兩點:
Lamda 表達式本質上回生成匿名類,在性能敏感的模塊慎用由於 Jack 編譯器不會產生.class 中間文件,因此在.class 上做 trick 的一些庫或者項目可能就會失效或者出問題。因此在使用之前,一定要好好測試。ConnectivityManager.getRestrictBackgroundStatus()
接口獲取本應用流量控制情況。Key Attestation:對於絕大部分應用並不需要仔細研究的 feature,甚至可以當做不存在,但是對於我個人所做的生物認證項目來說,可謂是非常重要的 feature。針對文件目錄或類型申請權限:實話實說,這個也算是一個很重要的 feature。從 Android 6.0 開始,如果需要使用存儲空間,包括讀寫,需要動態申請權限。然而對於大部分應用來說,都需要申請這個權限,而且一旦用戶允許,應用就可以為所欲為。因此,Android N 中允許應用聲明僅僅授權某個文件夾或者文件類型的存儲。
禁止 Native 動態鏈接系統庫
這一點 Android Developer 沒有講,至少暫時沒有講
還記得之前我說的微信升級到 N 會 Crash 麼?實際上就是這個原因。
自 Android N 開始,系統將禁止第三方應用 so 文件鏈接系統 lib 庫,包括並不限於 libcrypto.so,libandroidruntime.so,libicu.so,libbinder.so。動態鏈接上述庫輕則彈 Toast 提示,重則直接 crash。Android 此舉原因大家可以討論,但是事實已然如此,盡管對於大多數應用而言並無妨礙,但是對於類似微信這種在底層做了大量優化和調用的應用來說還是很傷腦筋的。至於解決方法。。。暫時只想到了改用靜態鏈接,對於包的大小增加並不會太大。如果有更好的方法,歡迎大家討論。
實話實說,這次 Android N 的更新對於我們程序員來說還是干貨滿滿,滿到我有些話想說。
前面說的都是 Android N,現在終於開始講扯淡了。實際上,從 Android L 開始,Google 就已經開始反省自己過分開放的策略。原本後台任務滿天飛的系統,現在漸漸地被控制得有序起來。比如 Android L 發布的 JobScheduler,Android M 發布的Doze模式和 APP Standby,Android N的Doze 加強以及瘦身計劃,無一不是在限制系統的後台任務數量以及計算強度。亡羊補牢,不知是否為時未晚。
同時,關於設計方面,Material Design 推出已經接近兩年,盡管有很多應用已經適配,但是包括微信、Facebook、Twitter 在內的很多主流應用仍然在堅持使用自己的設計語言。誠然,這裡有可以理解的風格統一之考慮, MD 本身也有很多缺陷,但是我們很高興能看到的是 MD 自身在不斷的調整優化,越來越成為一個漂亮的並且優秀的設計,其層次感以及靈動性無處不撩撥著用戶的神經。所以,是不是仍有很多人抱著2.3混亂局面或者4.0不那麼優秀的 Android Design 來臆測 Android 的設計風格?也許用著 iOS 的諸位對於 Android 的印象依然是 2.x 時代那個臃腫的、落後的以及。。額,難看的形象。就像這樣:
這是2011年左右,畢竟是5年前,那時 iPhone 上的應用也並不好看,不過還是比 Android 要強很多。但是現在 Android 應用已經長這樣了(系統自帶應用):
個人認為比 Apple 的設計。。。(為了防止引戰)至少並不差吧。
其實,這裡說了這麼多,精通讀心術的我也能想到大家心中的疑問:碎片化如此的 Android 市場,我們就算是適配了 N 的特性,大家也沒有這麼快用上,還是歇著吧。嗯,關於碎片化,首先,Android 目前版本分布是醬紫的(來自 Google 官方,鏈接http://developer.android.com/about/dashboards/index.html)
也就是說,至少截止到今天,接近40%的人的設備已經是 Android 5.0 以及以上,按照如今廠商發貨的速度,目測一兩個月內比例就會過半。平心而論,針對這半數用戶,有幾家應用做到了完美支持?無論是 UI 還是具體功能,大部分應用應該都是在4.x,甚至2.x版本的基礎上填坑,fix 新版本上的 crash,有幾家用到了新的特性,新的 feature 呢?而大家以為占主流的2.3系統,實際上已經不足3%,是不是仍然有很多應用的 target api 仍然是4.x以下?
而且 Google 現在很雞賊啊(這一點謝老大提醒),一年發布一個大版本,前年5.0,去年6.0,今年7.0,你說 Google 都到7.0了你還好意思連5.0都不上?這一點實際上對於解決碎片化是非常有幫助的。
面對占市場份額近7成的 Android 設備本身並不需要救助,一直都沒有放棄發展,欣欣向榮。相反,需要救助的是我們在 Android 上的應用,低質量的應用實現已經威脅到了我們自身。不僅僅是要依靠產品經理,作為程序員,我們也要學會自救。
本文實例講述了Android編程實現自定義PopupMenu樣式。分享給大家供大家參考,具體如下:PopupMenu是Android中一個十分輕量級的組件。與PopupW
背景相信大家對Android Studio已經不陌生了,Android Studio是Google於2013 I/O大會針對Android開發推出的新的開發工具,目前很多
activity類處於android.app包中,繼承關系:extends ContextThemeWrapperimplements LayoutInflater.Fa
Android是基於Java的,所以也分主線程,子線程!主線程:實現業務邏輯、UI繪制更新、各子線程串連,類似於將軍;子線程:完成耗時(聯網取數據、SD卡數據加載、後台長