这两天51cto上的一个粉丝朋友问了我一个问题,Ability之间使用Sequenceable序列化传递数据,如何传递Uri类型数据?网上确实也没有介绍这个使用的demo,为了帮他解决问题,自己帮他写了一个demo,顺手发布一篇博客和源代码。
seralizable是在java api中的类,用它也可以实现序列化,而在android中也有一个类使对象序列化,那就是parcelable,而在HarmonyOS中用Sequenceable来进行序列化。
那么它们之间有什么区别呢?
seralizable:序列化到本地,是一个持久化的操作,效率慢一点
parcelable:只存在于内存,程序结束,序列化后的对象就不存在了。效率快一点
Sequenceable:等同parcelable在Android中的作用。
下面我编写两个AbilitySlice之间互相跳转来传递数据
MainAbilitySlice对应的布局文件代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <DirectionalLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:width="match_parent"
- ohos:orientation="vertical">
- <Text
- ohos:id="$+id:text_helloworld"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:background_element="$graphic:background_ability_main"
- ohos:layout_alignment="horizontal_center"
- ohos:text="Hello World"
- ohos:text_size="50"
- />
- </DirectionalLayout>
就是系统自动生成的helloworld,我偷懒就没修改了,核心不在这里。
再创建一个TestSlice,布局代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <DirectionalLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:width="match_parent"
- ohos:orientation="vertical">
- <Text
- ohos:id="$+id:text_helloworld"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:background_element="$graphic:background_ability_main"
- ohos:layout_alignment="horizontal_center"
- ohos:text="TEST"
- ohos:text_size="50"
- />
- </DirectionalLayout>
为了要在两个Slice中间传递一个序列化对象数据,需要先创建一个实体类,并且实现Sequenceable接口,这里才是整个的核心代码,如下:
- package com.xdw.sequencedemo;
- import ohos.utils.Parcel;
- import ohos.utils.Sequenceable;
- import ohos.utils.net.Uri;
- /**
- * Created by 夏德旺 on 2021/2/26 10:39
- */
- public class Student implements Sequenceable {
- private int number;
- private String name;
- private Uri uri;
- public Student() {
- }
- public Student(int number, String name, Uri uri) {
- this.number = number;
- this.name = name;
- this.uri = uri;
- }
- public int getNumber() {
- return number;
- }
- public void setNumber(int number) {
- this.number = number;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Uri getUri() {
- return uri;
- }
- public void setUri(Uri uri) {
- this.uri = uri;
- }
- //上面是传统的实体类的构造函数和getter、setter
- //下面是序列化的核心
- //向包裹中写入数据,包裹可以理解为一块内存区
- public boolean marshalling(Parcel out) {
- out.writeSequenceable(uri); //注意Uri类型的写法和普通数据类型有所不同
- return out.writeInt(number) && out.writeString(name);
- }
- //从包裹中读取数据
- public boolean unmarshalling(Parcel in) {
- this.number = in.readInt();
- this.name = in.readString();
- return in.readSequenceable(uri); //注意Uri类型的写法和普通数据类型有所不同
- }
- //序列化对象的内部构造器,必须实现
- public static final Sequenceable.Producer
- PRODUCER = new Sequenceable.Producer
- () {
- public Student createFromParcel(Parcel in) { //从包裹中获取数据构造对象
- // Initialize an instance first, then do customized unmarshlling.
- Student instance = new Student();
- instance.unmarshalling(in);
- return instance;
- } //必须实现Producer
- };
- }
下面编写MainAbilitySlice的代码,给Text控件添加一个点击事件来跳转页面并且传递一个student参数
- package com.xdw.sequencedemo.slice;
- import com.xdw.sequencedemo.ResourceTable;
- import com.xdw.sequencedemo.Student;
- import ohos.aafwk.ability.AbilitySlice;
- import ohos.aafwk.content.Intent;
- import ohos.agp.components.Component;
- import ohos.agp.components.Text;
- import ohos.agp.window.dialog.ToastDialog;
- import ohos.utils.net.Uri;
- public class MainAbilitySlice extends AbilitySlice {
- private Text text;
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- text = (Text)findComponentById(ResourceTable.Id_text_helloworld);
- text.setClickedListener(new Component.ClickedListener() {
- @Override
- public void onClick(Component component) {
- Intent intent1 = new Intent();
- Student student = new Student();
- student.setNumber(1);
- student.setName("夏德旺");
- Uri uri = Uri.parse("http://www.xiadewang.com:8080/login?username=xdw&password=123");
- String scheme = uri.getScheme();
- //new ToastDialog(getContext()).setText("scheme="+scheme).show();
- student.setUri(uri);
- intent1.setParam("student",student);
- present(new TestSlice(),intent1);
- }
- });
- }
- @Override
- public void onActive() {
- super.onActive();
- }
- @Override
- public void onForeground(Intent intent) {
- super.onForeground(intent);
- }
- }
编写TestSlice的代码接收传递过来的student参数,并且通过toast展示
- package com.xdw.sequencedemo.slice;
- import com.xdw.sequencedemo.ResourceTable;
- import com.xdw.sequencedemo.Student;
- import ohos.aafwk.ability.AbilitySlice;
- import ohos.aafwk.content.Intent;
- import ohos.agp.window.dialog.ToastDialog;
- import ohos.utils.net.Uri;
- /**
- * Created by 夏德旺 on 2021/2/26 10:39
- */
- public class TestSlice extends AbilitySlice {
- @Override
- protected void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_slice_test);
- if(intent!=null){
- Student student = intent.getSequenceableParam("student");
- String name = student.getName();
- Uri uri = student.getUri();
- //new ToastDialog(getContext()).setText("name="+name).show();
- new ToastDialog(getContext()).setText("scheme="+uri.getScheme()).show();
- }
- }
- @Override
- protected void onActive() {
- super.onActive();
- }
- @Override
- protected void onForeground(Intent intent) {
- super.onForeground(intent);
- }
- }
到此,代码编写完成,下面是运行测试图:
这里也顺便完美解决了之前51cto上的粉丝朋友问我的Sequenceable对象无法读取Uri数据的问题。