HarmonyOS 分布式新聞分享
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
1. 介紹
HarmonyOS支持應(yīng)用以Ability為單位進(jìn)行部署,Ability可以分為FA(Feature Ability)和PA(Particle Ability)兩種類型,本篇Codelab將會使用到Page Ability以及Service Ability來進(jìn)行開發(fā),其中Page Ability是FA唯一支持的模板,用于提供與用戶交互的能力,Service Ability是PA(Particle Ability)的一種,用于提供后臺運(yùn)行任務(wù)的能力。除此之外,您還將使用到HarmonyOS中的常用控件如:ListContainer,Image等,以及跨設(shè)備拉起FA的能力來共同實(shí)現(xiàn)一個基于分布式的HarmonyOS簡易新聞客戶端。
最終效果預(yù)覽
我們最終會構(gòu)建一個簡易的HarmonyOS新聞客戶端。應(yīng)用包含兩級頁面,分別是主頁面和詳情頁面,兩個頁面都展示了豐富的HarmonyOS組件,其中詳情頁的實(shí)現(xiàn)邏輯中還展示了如何通過調(diào)用相應(yīng)接口,實(shí)現(xiàn)跨設(shè)備拉起FA。本篇Codelab我們將會一起完成這個客戶端,其中包括:
1.頂部ListContainer以及新聞列表ListContainer
2.每條新聞的文本框以及圖像
3.布局及頁面跳轉(zhuǎn)
4.設(shè)備發(fā)現(xiàn)以及跨設(shè)備拉起FA

2. 搭建HarmonyOS環(huán)境
安裝DevEco Studio,詳情請參考DevEco Studio下載。
設(shè)置DevEco Studio開發(fā)環(huán)境,DevEco Studio開發(fā)環(huán)境需要依賴于網(wǎng)絡(luò)環(huán)境,需要連接上網(wǎng)絡(luò)才能確保工具的正常使用,可以根據(jù)如下兩種情況來配置開發(fā)環(huán)境:
如果可以直接訪問Internet,只需進(jìn)行下載HarmonyOS SDK操作。
如果網(wǎng)絡(luò)不能直接訪問Internet,需要通過代理服務(wù)器才可以訪問,請參考配置開發(fā)環(huán)境。
說明:
如需要在手機(jī)中運(yùn)行程序,則需要提前申請證書,如使用模擬器可忽略。
你可以通過如下設(shè)備完成Codelab:
開啟開發(fā)者模式的HarmonyOS真機(jī)
DevEco Studio中的手機(jī)模擬器(模擬器暫不支持分布式調(diào)試)
3. 代碼結(jié)構(gòu)解讀
本篇Codelab只對核心代碼進(jìn)行講解,對于完整代碼,我們會在參考中提供下載方式,接下來我們會用一小節(jié)來講解整個工程的代碼結(jié)構(gòu):
- INewsDemoIDL.idl:存放在entry\src\main\idl\com\huawei\newsdemo目錄下,接口中定義了tranShare方法用來實(shí)現(xiàn)不同設(shè)備之間的通信。
- bean:NewsInfo封裝了新聞信息,NewsType封裝了新聞類型。
- provider:DevicesListProvider,NewsListProvider,NewsTypeProvider,分別為設(shè)備列表,主頁新聞列表以及新聞類型的provider,主要作用為高效傳遞和使用相關(guān)數(shù)據(jù)。
- slice:NewsListAbilitySlice,NewsDetailAbilitySlice分別為進(jìn)入應(yīng)用的主頁面和詳情頁面,同時里面也展現(xiàn)了我們大部分的邏輯實(shí)現(xiàn)。
- utils:存放所有封裝好的公共方法,如CommonUtils,DialogUtils等。
- NewsAbility:動態(tài)權(quán)限的申請以及頁面路由信息處理。
- SharedService:供遠(yuǎn)端連接的Service Ability。
- manager:該目錄下的文件為INewsDemoIDL.idl在編譯時自行生成,初始生成位置為entry\build\generated\source\idl\com\huawei\newsdemo。
- resources:存放工程使用到的資源文件,其中resources\base\layout下存放xml布局文件;resources\base\media下存放圖片資源;resources\rawfile下存放應(yīng)用使用的新聞數(shù)據(jù)json文件。
- config.json:配置文件

4. 添加主頁頂部新聞類型
首先為我們的應(yīng)用添加頂部新聞類型,用于切換不同類別的新聞,我們會使用到ListContainer控件,有關(guān)ListContainer的更多知識,可以參考HarmonyOS JAVA通用組件。
首先需要在布局文件中對控件進(jìn)行聲明,在resources\base\layout\news_list_layout.xml布局文件中有如下代碼:
- <ListContainer
- ohos:id="$+id:selector_list"
- ohos:width="match_parent"
- ohos:height="40vp"
- ohos:orientation="horizontal"
- />
此外我們還定義了selectorListContainer變量進(jìn)行關(guān)聯(lián),在NewsListAbilitySlice.java的initView()方法中有如下代碼:
- selectorListContainer = (ListContainer) findComponentById(ResourceTable.Id_selector_list);
添加監(jiān)聽
在切換不同類別新聞的時候,下面展示的新聞列表項(xiàng)會跟隨切換,所以我們需要為這個ListContainer設(shè)置一個監(jiān)聽,在NewsListAbilitySlice.java的initListener()方法中添加:
- selectorListContainer.setItemClickedListener(
- (listContainer, component, position, id) -> {
- // 設(shè)置選中后的放大效果
- setCategorizationFocus(false);
- selectText = (Text) component.findComponentById(ResourceTable.Id_news_type_text);
- setCategorizationFocus(true);
- newsDataList.clear();
- for (NewsInfo mTotalNewsData : totalNewsDataList) {
- if (selectText.getText().equals(mTotalNewsData.getType()) || id == 0) {
- newsDataList.add(mTotalNewsData);
- }
- }
- updateListView();
- });
聲明NewsTypeProvider
為了方便我們的應(yīng)用更加高效和便捷的使用數(shù)據(jù),我們將應(yīng)用中用到的新聞數(shù)據(jù)事先預(yù)置在resources/rawfile目錄下的兩個json文件中,此外我們還聲明了一些Provider,便于數(shù)據(jù)的獲取和傳遞,其中獲取新聞類別的NewsTypeProvider如下:
- @Override
- public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
- ViewHolder viewHolder;
- Component temp = component;
- if (temp == null) {
- temp = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_news_type_layout, null, false);
- // 將所有子組件通過ViewHolder綁定到列表項(xiàng)實(shí)例
- viewHolder = new ViewHolder();
- viewHolder.title = (Text) temp.findComponentById(ResourceTable.Id_news_type_text);
- component.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) temp.getTag();
- }
- viewHolder.title.setText(mNewsTypeList.get(position).getName());
- return temp;
- }
我們定義了initData方法來解析json文件中的新聞數(shù)據(jù),并將這些數(shù)據(jù)傳遞給provider,在NewsListAbilitySlice.java的initData()添加如下代碼:
- private void initData() {
- Gson gson = new Gson();
- List<NewsType> newsTypeList =
- gson.fromJson(
- CommonUtils.getStringFromJsonPath(this, "entry/resources/rawfile/news_type_datas.json"),
- new TypeToken<List<NewsType>>(){ }.getType());
- newsTypeProvider = new NewsTypeProvider(newsTypeList, this);
- }
添加切換效果
在切換不同類別新聞的時候,增加了一個放大效果,在setCategorizationFocus()中添加如下代碼:
- private void setCategorizationFocus(boolean isFocus) {
- if (selectText == null) {
- return;
- }
- if (isFocus) {
- selectText.setTextColor(
- new Color(CommonUtils.getColor(NewsListAbilitySlice.this, ResourceTable.Color_news_type_text_on)));
- selectText.setScaleX(FOCUS_TEXT_SIZE);
- selectText.setScaleY(FRCUS_TEXT_SIZE);
- } else {
- selectText.setTextColor(
- new Color(CommonUtils.getColor(NewsListAbilitySlice.this, ResourceTable.Color_news_type_text_off)));
- selectText.setScaleX(UNFOCUS_TEXT_SIZE);
- selectText.setScaleY(UNFOCUS_TEXT_SIZE);
- }
所以在進(jìn)行類別切換的時候,將會得到如下效果:

5. 添加主頁新聞列表項(xiàng)
新聞列表項(xiàng)布局
主頁面的布局除了有上方的頂部欄,還由下方的新聞列表項(xiàng)構(gòu)成,整個新聞列表項(xiàng)是一個ListContainer,同樣我們先來看看在new_list_layout.xml中是如何定義的:
- <ListContainer
- ohos:id="$+id:news_container"
- ohos:width="match_parent"
- ohos:height="match_parent"/>
整個新聞列表項(xiàng)由多個新聞item構(gòu)成,每個item又由標(biāo)題和圖片構(gòu)成,每個item在item_news_layout.xml布局中是這樣定義的:
- <DirectionalLayout
- ohos:height="109.5vp"
- ohos:width="match_parent"
- ohos:orientation="horizontal"
- ohos:padding="10vp">
- <Text
- ohos:id="$+id:item_news_title"
- ohos:height="match_content"
- ohos:width="0vp"
- ohos:max_text_lines="3"
- ohos:multiple_lines="true"
- ohos:right_padding="20vp"
- ohos:text_size="18vp"
- ohos:weight="3"/>
- <Image
- ohos:id="$+id:item_news_image"
- ohos:height="match_parent"
- ohos:width="0vp"
- ohos:scale_mode="stretch"
- ohos:weight="2"/>
- </DirectionalLayout>
聲明NewsListProvider
和頂部新聞類型一樣,每個新聞item中的title和image也是利用provider傳遞的,在NewsListProvider.java中有如下代碼:
- @Override
- public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
- ViewHolder viewHolder;
- Component temp = component;
- if (temp == null) {
- component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_news_layout, null, false);
- // 將所有子組件通過ViewHolder綁定到列表項(xiàng)實(shí)例
- viewHolder = new ViewHolder();
- viewHolder.title = (Text) temp.findComponentById(ResourceTable.Id_item_news_title);
- viewHolder.image = (Image) temp.findComponentById(ResourceTable.Id_item_news_image);
- temp.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) temp.getTag();
- }
- viewHolder.title.setText(newsInfoList.get(i).getTitle());
- viewHolder.image.setPixelMap(CommonUtils.getPixelMapFromPath(context, newsInfoList.get(i).getImgUrl()));
- return temp;
- }
同樣,newsListProvider的數(shù)據(jù)也是在initData的時候進(jìn)行賦值的,所以需要在NewsListAbilitySlice的initData()中添加:
- totalNewsDataList =
- gson.fromJson(
- CommonUtils.getStringFromJsonPath(this, "entry/resources/rawfile/news_datas.json"),
- new TypeToken<List<NewsInfo>>(){ }.getType());
- newsDataList = new ArrayList<>();
- newsDataList.addAll(totalNewsDataList);
- newsListProvider = new NewsListProvider(newsDataList, this);
到此我們完成了數(shù)據(jù)的加載和解析,接下來是為item添加點(diǎn)擊事件。
添加監(jiān)聽
我們點(diǎn)擊某個具體新聞item的時,應(yīng)用會跳轉(zhuǎn)到全局詳情頁面,這時要為新聞item添加一個監(jiān)聽,在NewsListAbilitySlice.java的initListener()中添加:
- newsListContainer.setItemClickedListener(
- (listContainer, component, position, id) -> {
- Intent intent = new Intent();
- Operation operation =
- new Intent.OperationBuilder()
- .withBundleName(getBundleName())
- .withAbilityName(NewsAbility.class.getName())
- .withAction("action.detail")
- .build();
- intent.setOperation(operation);
- intent.setParam(NewsDetailAbilitySlice.INTENT_TITLE, newsDataList.get(position).getTitle());
- intent.setParam(NewsDetailAbilitySlice.INTENT_READ, newsDataList.get(position).getReads());
- intent.setParam(NewsDetailAbilitySlice.INTENT_LIKE, newsDataList.get(position).getLikes());
- intent.setParam(NewsDetailAbilitySlice.INTENT_CONTENT, newsDataList.get(position).getContent());
- intent.setParam(NewsDetailAbilitySlice.INTENT_IMAGE, newsDataList.get(position).getImgUrl());
- startAbility(intent);
- });
這里的startAbility()是我們頁面跳轉(zhuǎn)的關(guān)鍵方法,參數(shù)intent里面存放了要跳轉(zhuǎn)的bundle name,ability name,詳情頁面的title,imgurl等重要參數(shù)。
6. 詳情頁頁面布局
新聞詳情頁的布局相比于新聞主頁稍微有些復(fù)雜,整體由DependentLayout布局嵌套DirectionalLayout布局、ScrollView和其他控件構(gòu)成,我們把整體頁面分為頂部,底部,和中部。并在resources\base\layout\new_detail_laylout.xml中實(shí)現(xiàn)詳情頁的布局。
頂部
頂部是由DirectionalLayout加上Text組件構(gòu)成,分別對應(yīng)了左側(cè)的圖標(biāo)和NewsDemo以及右側(cè)的reads和likes,實(shí)現(xiàn)效果及布局部分代碼如下:

- <DirectionalLayout
- ohos:width="match_parent"
- ohos:height="match_content"
- ohos:alignment="vertical_center"
- ohos:orientation="horizontal">
- <Text
- ohos:id="$+id:title_icon"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:weight="1"
- ohos:text="NewsDemo"
- ohos:text_size="20fp"/>
- <Text
- ohos:id="$+id:read_num"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text_size="10fp"
- ohos:right_margin="10vp"/>
- <Text
- ohos:id="$+id:like_num"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text_size="10fp"/>
- </DirectionalLayout>
中部
頁面的中間部分由新聞標(biāo)題Text,縮略圖Image,新聞內(nèi)容Text構(gòu)成,實(shí)現(xiàn)效果及布局部分代碼如下:

- <Text
- ohos:id="$+id:title_text"
- ohos:width="match_parent"
- ohos:height="match_content"
- ohos:text_size="18fp"
- ohos:max_text_lines="4"
- ohos:multiple_lines="true"
- ohos:text_color="#000000"
- ohos:top_margin="10vp"/>
- <Image
- ohos:id="$+id:image_content"
- ohos:width="match_parent"
- ohos:scale_mode="stretch"
- ohos:height="300vp"
- ohos:top_margin="10vp"/>
- <Text
- ohos:id="$+id:title_content"
- ohos:width="match_parent"
- ohos:height="match_content"
- ohos:multiple_lines="true"
- ohos:text_color="#708090"
- ohos:text_size="16vp"
- ohos:text_alignment="center_horizontal"
- ohos:top_margin="5vp"/>
底部
頁面的底部由DirectionalLayout加上TextField和Image控件構(gòu)成,對應(yīng)輸入評論和幾個按鈕,具體效果和部分布局代碼如下:

- <DirectionalLayout
- ohos:id="$+id:bottom_layout"
- ohos:align_parent_bottom="true"
- ohos:width="match_parent"
- ohos:height="50vp"
- ohos:orientation="horizontal"
- ohos:background_element="#ffffff"
- ohos:alignment="vertical_center"
- ohos:left_padding="20vp"
- ohos:right_padding="20vp"
- >
- <TextField
- ohos:id="$+id:text_file"
- ohos:width="160vp"
- ohos:height="30vp"
- ohos:left_padding="5vp"
- ohos:right_padding="10vp"
- ohos:text_alignment="vertical_center"
- ohos:text_size="15vp"
- ohos:hint="Enter a comment."
- ohos:background_element="$graphic:corner_bg_comment"/>
- <Image
- ohos:id="$+id:button1"
- ohos:width="20vp"
- ohos:height="20vp"
- ohos:image_src="$media:message_icon"
- ohos:scale_mode="stretch"
- ohos:left_margin="20vp"/>
- <Image
- ohos:id="$+id:button2"
- ohos:width="20vp"
- ohos:height="20vp"
- ohos:image_src="$media:collect_icon"
- ohos:scale_mode="stretch"
- ohos:left_margin="20vp"/>
- <Image
- ohos:id="$+id:button3"
- ohos:width="20vp"
- ohos:height="20vp"
- ohos:image_src="$media:like_icon"
- ohos:scale_mode="stretch"
- ohos:left_margin="20vp"/>
- <Image
- ohos:id="$+id:button4"
- ohos:width="20vp"
- ohos:height="20vp"
- ohos:image_src="$media:share_icon"
- ohos:scale_mode="stretch"
- ohos:left_margin="20vp"/>
- </DirectionalLayout>
7. 詳情頁數(shù)據(jù)初始化
接受來自NewsListAbilitySlice頁面的數(shù)據(jù)
我們在添加新聞列表項(xiàng)那一節(jié)中說明了新聞頁面的title,imgurl等重要參數(shù)是如何存放的,現(xiàn)在我們一起看下在詳情頁是如何獲取的。在NewsDetailAbilitySlice.java的onStart()中有如下代碼:
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_news_detail_layout);
- reads = intent.getStringParam(INTENT_READ);
- likes = intent.getStringParam(INTENT_LIKE);
- title = intent.getStringParam(INTENT_TITLE);
- content = intent.getStringParam(INTENT_CONTENT);
- image = intent.getStringParam(INTENT_IMAGE);
- }
之前存放在intent中的參數(shù),現(xiàn)在在onStart()中逐一進(jìn)行取出。
布局和控件的初始化
除了需要聲明xml來實(shí)現(xiàn)布局以外,還需要在NewsDetailAbilitySlice.java的onStart()中添加initView()方法進(jìn)行初始化:
- private void initView() {
- parentLayout = (DependentLayout) findComponentById(ResourceTable.Id_parent_layout);
- commentFocus = (TextField) findComponentById(ResourceTable.Id_text_file);
- iconShared = (Image) findComponentById(ResourceTable.Id_button4);
- Text newsRead = (Text) findComponentById(ResourceTable.Id_read_num);
- Text newsLike = (Text) findComponentById(ResourceTable.Id_like_num);
- Text newsTitle = (Text) findComponentById(ResourceTable.Id_title_text);
- Text newsContent = (Text) findComponentById(ResourceTable.Id_title_content);
- Image newsImage = (Image) findComponentById(ResourceTable.Id_image_content);
- newsRead.setText("reads: " + reads);
- newsLike.setText("likes: " + likes);
- newsTitle.setText("Original title: " + title);
- newsContent.setText(content);
- newsImage.setPixelMap(CommonUtils.getPixelMapFromPath(this, image));
- }
添加監(jiān)聽
我們在點(diǎn)擊頁面底部右下角的分享按鈕的時候,會進(jìn)行設(shè)備發(fā)現(xiàn)操作,并將發(fā)現(xiàn)的設(shè)備列表進(jìn)行展示,此處我們設(shè)置了兩個監(jiān)聽,在NewsDetailAbilitySlice.java的onStart()中添加initListener():
- private void initListener() {
- parentLayout.setTouchEventListener(
- (component, touchEvent) -> {
- if (commentFocus.hasFocus()) {
- commentFocus.clearFocus();
- }
- return true;
- });
- iconShared.setClickedListener(
- v -> {
- initDevices();
- showDeviceList();
- });
- }
parentLayout的監(jiān)聽事件用來監(jiān)聽觸控焦點(diǎn)是否在設(shè)備列表Dialog上,iconShared的監(jiān)聽事件用來監(jiān)聽分享按鈕被是否被點(diǎn)擊。

8. 設(shè)備發(fā)現(xiàn)
上一節(jié)我們了解到當(dāng)分享按鈕被點(diǎn)擊的時候會觸發(fā)監(jiān)聽,進(jìn)行設(shè)備發(fā)現(xiàn),那么觸發(fā)監(jiān)聽后,是如何進(jìn)行設(shè)備發(fā)現(xiàn)的?
在initListener()中有兩個有關(guān)設(shè)備發(fā)現(xiàn)的方法:initDevices()和showDeviceList()。initDevices()方法調(diào)用接口實(shí)現(xiàn)設(shè)備發(fā)現(xiàn),并將發(fā)現(xiàn)到的設(shè)備存儲到List中,需要如下代碼實(shí)現(xiàn):
- private void initDevices() {
- if (devices.size() > 0) {
- devices.clear();
- }
- List<DeviceInfo> deviceInfos =
- DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
- devices.addAll(deviceInfos);
- }
發(fā)現(xiàn)到的設(shè)備,通過Dialog進(jìn)行顯示,您可以選擇一個目標(biāo)設(shè)備進(jìn)行跨設(shè)備流轉(zhuǎn),需要在NewsDetailAbilitySlice.java的showDeviceList()中添加如下代碼:
- private void showDeviceList() {
- // 設(shè)備列表dialog
- dialog = new CommonDialog(NewsDetailAbilitySlice.this);
- dialog.setAutoClosable(true);
- dialog.setTitleText("HarmonyOS devices");
- dialog.setSize(DIALOG_SIZE_WIDTH, DIALOG_SIZE_HEIGHT);
- ListContainer devicesListContainer = new ListContainer(getContext());
- DevicesListAdapter devicesListProvider = new DevicesListProvider(devices, this);
- devicesListContainer.setItemProvider(devicesListAdapter);
- devicesListContainer.setItemClickedListener(
- (listContainer, component, position, id) -> {
- dialog.destroy()
- // 跨設(shè)備拉起FA
- startAbilityFA(devices.get(position).getDeviceId());
- });
- devicesListAdapter.notifyDataChanged();
- dialog.setContentCustomComponent(devicesListContainer);
- dialog.show();
- }

當(dāng)我們選擇某個設(shè)備的時候,被選擇的設(shè)備會拉起指定的FA頁面,被拉起的FA頁面會和發(fā)起請求的那一端保持一致。
9. 跨設(shè)備協(xié)同
連接Service Ability
那么跨設(shè)備協(xié)同又是如何實(shí)現(xiàn)的?發(fā)現(xiàn)的設(shè)備列表也是通過一個ListContainer來展示的,設(shè)備列表也有對應(yīng)的xml和變量聲明,這里不再贅述。對于每一個設(shè)備item,我們添加了監(jiān)聽用來進(jìn)行跨設(shè)備拉起FA,需要在NewsDetailAbilitySlice的showDeviceList()中添加startAlibityFA()方法,具體代碼如下:
- private void startAbilityFA(StringdevicesId) {
- Intent intent = new Intent();
- Operation operation =
- new Intent.OperationBuilder()
- .withDeviceId(devicesId)
- .withBundleName(getBundleName())
- .withAbilityName(SharedService.class.getName())
- // 該FLAG用于分布式跨設(shè)備場景
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- intent.setOperation(operation);
- boolean connectFlag =
- // 連接遠(yuǎn)端 Service Ability
- connectAbility(
- intent,
- new IAbilityConnection() {
- @Override
- public void onAbilityConnectDone(
- ElementName elementName, IRemoteObject iRemoteObject, int i) {
- INewsDemoIDL sharedManager = NewsDemoIDLStub.asInterface(iRemoteObject);
- try {
- sharedManager.tranShare(title, reads, likes, content, image);
- } catch (RemoteException e) {
- LogUtil.i(TAG, "connect successful,but have remote exception");
- }
- }
- @Override
- public void onAbilityDisconnectDone(ElementName elementName, int i) {
- disconnectAbility(this);
- }
- });
- DialogUtil.toast(
- this, connectFlag ? "Sharing succeeded!" : "Sharing failed. Please try again later.", WAIT_TIME);
- }
方法中我們?yōu)閕ntent設(shè)置了bundlename,abilityname,devicesId等參數(shù),通過connectAbility方法實(shí)現(xiàn)與遠(yuǎn)端Service Ability進(jìn)行連接,連接成功后,會在onAbilityConnectDone中調(diào)用tranShare方法將對端需要的數(shù)據(jù)傳遞過去。
遠(yuǎn)端Service Ability的定義
本端通過connectAbility連接遠(yuǎn)端的Service Ability,那么遠(yuǎn)端的Service Ability又是如何定義的?需要在SharedService.java中添加tranShare()方法,代碼如下:
- public void tranShare(String title, String reads, String likes, String content, String image) {
- Intent intent = new Intent();
- Operation operation =
- new Intent.OperationBuilder()
- .withBundleName(getBundleName())
- .withAbilityName(NewsAbility.class.getName())
- .withAction("action.detail")
- .build();
- intent.setOperation(operation);
- intent.setParam(NewsDetailAbilitySlice.INTENT_TITLE, title);
- intent.setParam(NewsDetailAbilitySlice.INTENT_READ, reads);
- intent.setParam(NewsDetailAbilitySlice.INTENT_LIKE, likes);
- intent.setParam(NewsDetailAbilitySlice.INTENT_CONTENT, content);
- intent.setParam(NewsDetailAbilitySlice.INTENT_IMAGE, image);
- startAbility(intent);
說明:
以上代碼僅demo演示參考使用
這樣便通過startAbility方法拉起了指定的FA,并將intent攜帶的參數(shù)一并傳遞過去。
—-結(jié)束
當(dāng)前實(shí)現(xiàn)遠(yuǎn)程啟動FA,需要至少兩個設(shè)備處于同一個分布式網(wǎng)絡(luò)中,可以通過操作如下配置實(shí)現(xiàn):
所有設(shè)備接入同一網(wǎng)絡(luò),
所有設(shè)備登陸相同華為賬號,
所有設(shè)備上開啟"設(shè)置->更多連接->多設(shè)備協(xié)同 "
10. 回顧和總結(jié)
在本篇Codelab中我們介紹了應(yīng)用的主頁面和詳情頁,在主頁面可以通過頂部的新聞類型切換不同類別的新聞,同時下面整個新聞列表項(xiàng)也會跟隨切換。點(diǎn)擊下方某個具體新聞item的時候,會進(jìn)行跳轉(zhuǎn)到新聞詳情頁面;在新聞詳情頁可以上下滑動查看新聞,并且點(diǎn)擊下方分享按鈕可以實(shí)現(xiàn)FA的跨設(shè)備協(xié)同,整體效果如下圖1和圖2:


11. 恭喜你
目前你已經(jīng)成功完成了Codelab并且學(xué)到了:
如何使用ListContainer等常用控件
如何進(jìn)行布局編寫及頁面跳轉(zhuǎn)
如何進(jìn)行設(shè)備發(fā)現(xiàn)以及FA的跨設(shè)備協(xié)同
12. 參考
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)