標籤:
今年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 Developer 的年代,這個非預設的特性實在不會引起他們的注意。
在 Android N 中,竟然直接支援了 multi-window!雖然這個特性並不驚豔,在 iOS 和三星的機型中早已支援,甚至在 Android M 中,也可以預埋了這個特性,並可以通過某些特殊方法開啟。然而,和 iOS 應用需要特殊聲明才能支援多視窗的特性不同,Android N竟然預設支援了多視窗。這意味著任何一個應用,無論 target-api 是否是 Android N,都支援從最近任務中長按應用標題列進入多視窗模式。這裡是個 demo。
預設支援也就意味著除非特殊聲明,任何應用都支援前述視屏所示效果,也就是說如果應用不針對這種模式進行完美適配,或者說用了絕對布局的話,你的應用就會。。。。呵呵呵。
當然,這種老掉牙的特性是不會引起高冷的 PM 的注意的,只會扔給開發狗交給我們去適配。那好吧,來一個 one more thing 刺激一下你:
在 Android N 中,將支援分屏情況下 drag and drop,讓這個4.0開始就支援 faeture 煥發了新生。這也就意味著你可以將一個應用內、甚至不同應用間的分屏情況將一個分螢幕控制項拖拽到另外一個分螢幕。也許可以用來拖拽圖片快速發圖,或者。。隨便你想幹什麼。
當然,從開發狗的角度來說,這裡有一點安全隱患:如果通過拖拽將資料傳遞過來,你甚至不知道來源是什麼。但是想想也是,畢竟用的和粘貼板一樣的介面,還能指望什麼呢?
另外,作為分屏的一種特殊形式,畫中畫(picture in picture)也得到了相應的支援。不過據 Google 的工程師說,畫中畫模式主推 Android TV 中應用(也許 Google 認為在手持功能上情境不足)。不過 whatever,現在很多功能已經可以通過浮窗介面實現。畫中畫對於做視頻應用或者有視頻支援功能的應用非常有協助。
此外,給程式員朋友們幾個小貼士
- 雖然分屏狀態下兩個應用都可見,但是對於非 Focus 狀態的應用當前是處於 onStop 狀態的,也就是說,並沒有實際在運行中。原本 onStop 的時候應用應該是不可見,但是現在可見了。。。原本的一些噁心邏輯注意修改下。
- 雖然分屏狀態下的應用不會 double 記憶體佔用,但是記憶體佔用肯定會比正常狀態大,注意分屏模式下即時釋放記憶體。
- 適配好你的程式,該加 scroll 的地方加 scroll。當然,如果原本的你的程式就已經針對多尺寸螢幕有了處理,就已經完美適配了這個模式
強化通知
通知欄一直是 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 aACTION_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 則並不會受到影響。
Java 8支援
早在前年開始研究 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 true7. }8. }9. compileOptions {10. sourceCompatibility JavaVersion.VERSION_1_811. targetCompatibility JavaVersion.VERSION_1_812. }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 的一些庫或者項目可能就會失效或者出問題。因此在使用之前,一定要好好測試。
其他應該注意的事項
- Data Saver:乍看上去是一個資料存放區的 API,感覺很興奮,結果點開一看是流量節省。。。好吧,博大精深的英文。從 Android N 開始,系統層級支援使用者針對每一個應用添加自己的流量控制限制。今後開發的時候需要先通過
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 上的應用,低品質的應用實現已經威脅到了我們自身。不僅僅是要依靠產品經理,作為程式員,我們也要學會自救。
【Bugly乾貨分享】關於 Android N 那些你不知道的事兒