HarmonyOS 分布式之仿抖音应用

想了解更多内容,布式请访问:

和华为官方合作共建的抖音鸿蒙技术社区

https://harmonyos.51cto.com

项目介绍

使用Java UI开发分布式仿抖音应用,上下滑动切换视频,应用评论功能,布式设备迁移功能:记录播放的抖音视频页和进度、评论数据。应用

效果演示

1.上下滑动切换视频、布式点击迁移图标,抖音弹框选择在线的应用设备,完成视频数据的布式迁移。

2.点击评论图标查看评论,抖音编辑评论内容并发送。应用点击迁移图标,布式弹框选择在线的抖音设备,完成评论数据的应用迁移。亿华云

项目结构

主要代码

1、上下滑动页面

页面切换用到系统组件PageSlider,默认左右切换,设置为上下方向:setOrientation(Component.VERTICAL);

import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.*; import java.util.ArrayList; import java.util.List; public class MainAbilitySlice extends AbilitySlice {      @Override     public void onStart(Intent intent) {          super.onStart(intent);         super.setUIContent(ResourceTable.Layout_ability_main);         // 查找滑动页面组件         PageSlider pageSlider = (PageSlider) findComponentById(ResourceTable.Id_pageSlider);         // 设置滑动方向为上下滑动         pageSlider.setOrientation(Component.VERTICAL);         // 集合测试数据         List<String> listData=new ArrayList<>();         listData.add("第一页");         listData.add("第二页");         listData.add("第三页");         // 设置页面适配器         pageSlider.setProvider(new PageSliderProvider() {              /**              * 获取当前适配器中可用视图的数量              */             @Override             public int getCount() {                  return listData.size();             }             /**              * 创建页面              */             @Override             public Object createPageInContainer(ComponentContainer container, int position) {                  // 查找布局                 Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_item_page, null, false);                 Text textContent = (Text) component.findComponentById(ResourceTable.Id_text_item_page_content);                 // 设置数据                 textContent.setText(listData.get(position));                 // 添加到容器中                 container.addComponent(component);                 return component;             }             /**              * 销毁页面              */             @Override             public void destroyPageFromContainer(ComponentContainer container, int position, Object object) {                  // 从容器中移除                 container.removeComponent((Component) object);             }             /**              * 检查页面是否与对象匹配              */             @Override             public boolean isPageMatchToObject(Component page, Object object) {                  return true;             }         });         // 添加页面改变监听器         pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() {              /**              * 页面滑动时调用              */             @Override             public void onPageSliding(int itemPos, float itemPosOffset, int itemPosOffsetPixels) { }             /**              * 当页面滑动状态改变时调用              */             @Override             public void onPageSlideStateChanged(int state) { }             /**              * 选择新页面时回调              */             @Override             public void onPageChosen(int itemPos) {                  // 在此方法下,切换页面获取当前页面的视频源,进行播放                 String data = listData.get(itemPos);             }         });     } } 

2、播放视频

视频播放使用Player,视频画面窗口显示使用SurfaceProvider。

import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.surfaceprovider.SurfaceProvider; import ohos.agp.graphics.SurfaceOps; import ohos.global.resource.RawFileDescriptor; import ohos.media.common.Source; import ohos.media.player.Player; import java.io.IOException; public class MainAbilitySlice extends AbilitySlice {      // 视频路径     private final String videoPath = "resources/rawfile/HarmonyOS.mp4";     // 播放器     private Player mPlayer;     @Override     public void onStart(Intent intent) {          super.onStart(intent);         super.setUIContent(ResourceTable.Layout_ability_main);         // 初始化播放器         mPlayer = new Player(getContext());         // 查找视频窗口组件         SurfaceProvider surfaceProvider = (SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);         // 设置视频窗口在顶层         surfaceProvider.pinToZTop(true);         // 设置视频窗口操作监听         if (surfaceProvider.getSurfaceOps().isPresent()) {              surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {                  /**                  * 创建视频窗口                  */                 @Override                 public void surfaceCreated(SurfaceOps holder) {                      try {                          RawFileDescriptor fileDescriptor = getResourceManager().getRawFileEntry(videoPath).openRawFileDescriptor();                         Source source = new Source(fileDescriptor.getFileDescriptor(),                                 fileDescriptor.getStartPosition(),                                 fileDescriptor.getFileSize()                         );                         // 设置媒体文件                         mPlayer.setSource(source);                         // 设置播放窗口                         mPlayer.setVideoSurface(holder.getSurface());                         // 循环播放                         mPlayer.enableSingleLooping(true);                         // 准备播放环境并缓冲媒体数据                         mPlayer.prepare();                         // 开始播放                         mPlayer.play();                     } catch (IOException e) {                          e.printStackTrace();                     }                 }                 /**                  * 视频窗口改变                  */                 @Override                 public void surfaceChanged(SurfaceOps holder, int format, int width, int height) { }                 /**                  * 视频窗口销毁                  */                 @Override                 public void surfaceDestroyed(SurfaceOps holder) { }             });         }     }     @Override     protected void onStop() {          super.onStop();         // 页面销毁,释放播放器         if (mPlayer != null) {              mPlayer.stop();             mPlayer.release();         }     } } 

3、跨设备迁移示例

跨设备迁移使用IAbilityContinuation接口。

1、在entry下的config.json配置权限

"reqPermissions": [       {          "name": "ohos.permission.DISTRIBUTED_DATASYNC"       },       {          "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"       },       {          "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"       }     ] 

2、实现IAbilityContinuation接口,说明:一个应用可能包含多个Page,仅需要在支持迁移的源码库Page中通过以下方法实现IAbilityContinuation接口。同时,此Page所包含的所有AbilitySlice也需要实现此接口。

import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.ability.IAbilityContinuation; import ohos.aafwk.content.Intent; import ohos.aafwk.content.IntentParams; import ohos.agp.components.Button; import ohos.agp.components.Text; import ohos.bundle.IBundleManager; import ohos.distributedschedule.interwork.DeviceInfo; import ohos.distributedschedule.interwork.DeviceManager; import java.util.List; public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation {      private String data = "";     String PERMISSION = "ohos.permission.DISTRIBUTED_DATASYNC";     @Override     public void onStart(Intent intent) {          super.onStart(intent);         super.setUIContent(ResourceTable.Layout_ability_main);         // 申请权限         if (verifySelfPermission(PERMISSION) != IBundleManager.PERMISSION_GRANTED) {              requestPermissionsFromUser(new String[]{ PERMISSION}, 0);         }         Button button = (Button)findComponentById(ResourceTable.Id_button);         Text text = (Text)findComponentById(ResourceTable.Id_text);         // 点击迁移         button.setClickedListener(component -> {              // 查询分布式网络中所有在线设备(不包括本地设备)的信息。             List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);             if (deviceList.size()>0) {                  // 启动迁移,指定的设备ID                 continueAbility(deviceList.get(0).getDeviceId());             }         });         // 显示迁移的数据         text.setText("迁移的数据:"+data);     }     /**      * 启动迁移时首次调用此方法      * @return 是否进行迁移      */     @Override     public boolean onStartContinuation() {          return true;     }     /**      * 迁移时存入数据      */     @Override     public boolean onSaveData(IntentParams intentParams) {          intentParams.setParam("data","测试数据");         return true;     }     /**      * 获取迁移存入的数据,在生命周期的onStart之前执行      */     @Override     public boolean onRestoreData(IntentParams intentParams) {          data= (String) intentParams.getParam("data");         return true;     }     /**      * 迁移完成      */     @Override     public void onCompleteContinuation(int i) { } } 

根据上面的核心代码示例,了解实现原理,接下来便可以结合实际需求完善功能了。

想了解更多内容,请访问:

和华为官方合作共建的亿华云计算鸿蒙技术社区

https://harmonyos.51cto.com

数据库
上一篇:探讨量子计算对数据中心基础设施的潜在影响
下一篇:云计算采用和人工智能如何推动数据中心发展?