Android P-Slices特性實踐
概述
在2018年穀歌I/O開發者大會上,谷歌釋出了萬眾期待的Android最新版本-Android P。Slice作為Android P版本更新的一大功能,其使用場景以及新API的使用也格外引人注目。
Slice其實是一個UI展示模組,它可以在搜尋APP、語音助手、關鍵字識別等動作中動態地顯示你的APP部分模組的內容,通過它,可以豐富地顯示你的APP當中的內容。Slice提供shortcut、small、large三種View顯示模板,開發者可以根據自身APP需求選擇合適的顯示模板。
開始使用
Tips
1.在開始使用之前,你需要更新最新版本的Android Studio,到目前我使用的最新版本為 Android Studio 3.3 Canary 3 。以便支援最新的Android擴充套件外掛,AndroidX。
2.下載安裝谷歌官方提供的Slice模組搜尋測試工具,[Slice Viewer sample]( Slice Viewer ) ,僅支援安卓4.4以上的手機除錯使用。
1.新建你的Android專案,在gradle中新增如下依賴:
implementation 'androidx.slice:slice-core:1.0.0-beta01' implementation 'androidx.slice:slice-builders:1.0.0-beta01'
2.為你的APP建立Slice,你需要在你的專案檔案中,點選右鍵選擇New… > Other > Slice Provider,編輯器將會自動幫你在AndroidManifest.xml中新增Provider:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.app"> ... <application> ... <provider android:name=".provider.MySliceProvider" android:authorities="com.xxx.xxxxxx.slicedemo.provider" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.app.slice.category.SLICE" /> <data android:host="guanjianhui.teach.com" android:pathPrefix="/hello" android:scheme="http" /> </intent-filter> </provider> ... </application> </manifest>
3.其中,SliceProvider繼承於ContentProvider,其APP間資料的傳遞通過
ContentProvider的方式,應用APP向搜尋APP對外提供其對應Slice的Uri,封裝成Slice物件通過Parcelable序列化的方式實現APP之間的資料傳遞。新建類繼承SliceProvider,並重寫onBindSlice()方法,在該方法裡可以編寫Slice展示模組中的相關邏輯程式碼:
@Override public Slice onBindSlice(Uri sliceUri) { if (getContext() == null) { return null; } SliceAction activityAction = createActivityAction(); ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY); // Create parent ListBuilder. if ("/hello".equals(sliceUri.getPath())) { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle("Hello World") .setPrimaryAction(activityAction) ); } else { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle("URI not recognized") .setPrimaryAction(activityAction) ); } return listBuilder.build(); }
Uri的scheme統一為content,如上述例子的Uri為:
content://com.xxx.xxxxxx.slicedemo.provider/hello4.跟notifications類似,你可以使用PendingIntents 來處理使用者的點選事件,比如點選Slice模組開啟宿主APP:
public Slice createSlice(Uri sliceUri) { if (getContext() == null) { return null; } SliceAction activityAction = createActivityAction(); return new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .addRow(new ListBuilder.RowBuilder() .setTitle("Perform action in app.") .setPrimaryAction(activityAction) ).build(); } public SliceAction createActivityAction() { if (getContext() == null) { return null; } return SliceAction.create( PendingIntent.getActivity( getContext(), 0, new Intent(getContext(), MainActivity.class), 0 ), IconCompat.createWithResource(getContext(), R.drawable.ic_home), ListBuilder.ICON_IMAGE, "Enter app" ); }
5.通過開始安裝的 Slice Viewer ,搜尋框中輸入對應Slice的URI地址,便可在搜尋APP中看到應用APP中新增的Slice模組:

Slice模板
ListBuilder
Slices通過ListBuilder類來建立。在ListBuilder中,你可以新增不同型別的行模組在你的Slice中進行展示。
SliceAction
對於每一個Slice來說,最基礎的構造實現類是SliceAction,在SliceAction你可以新增PendingIntent來實現使用者操作,比如Toggle選擇操作:
SliceAction toggleAction =SliceAction.createToggle(createToggleIntent(),"Toggle adaptive brightness",true);
SliceAction可以配置在搜尋APP中顯示的模組三種不同的顯示方式:
ICON_IMAGE:tiny size and tintable:

SMALL_IMAGE:small size and non-tintable:

LARGE_IMAGE: largest size and non-tintable:

模組構造Builder
對於每個Slice模組的建立構造,谷歌官方提供了HeaderBuilder、RowBuilder、GridBuilder、RangeBuilder模組四種構造器。其中,HeaderBuilder只支援一行頭部的展示view;RowBuilder可以新增一行view進行展示,如此前沒有新增header,則首行row預設為header;GridBuilder支援上述所說的三種模組展示方式;而RangeBuilder則支援進度條相關的view展示。
延時載入
對於一些需要耗時載入資料的操作,比如網路請求圖片等,可以採取與ListView載入圖片類似的方法,先本地載入一個預設的佔位資料,等耗時操作完成回調回來真實資料的時候呼叫getContentResolver().notifyChange(sliceUri) 方法,通知搜尋APP呼叫Slice Uri,完成真實資料的顯示。
結語
Slice的功能模板非常的強大,通過不同的builder組合可以在搜尋模組中搭配出豐富多彩的Slice,快速直達使用者想要的功能。但是Slice只提供了三種模板,自帶模板中對安卓原生控制元件的支援有所欠缺,比如ScollView等,可能需要使用者自定義自己的模板才能實現更強大的功能。
【附錄】

資料圖
需要資料的朋友可以加入Android架構交流QQ群聊:513088520
點選連結加入群聊【Android移動架構總群】: 加入群聊
獲取免費學習視訊,學習大綱另外還有像高階UI、效能優化、架構師課程、NDK、混合式開發(ReactNative+Weex)等Android高階開發資料免費分享。