上次讲了页面跳转,还留下首页的一个按钮没讲。

就是它,这个按钮的作用就是使当前端的业务可以向同网内的另一个端发请请求。

代码声明,本文中所有代码均采用此声明:

/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

我们先看下这个所谓的多端业务流转的倒底是个啥。

同时开启两个设备,都运行起咱们的项目。


A 设备点击流转按钮。


发起权限申请点允许。


输入内容后点按钮。


消息流转到 B 设备。

多端业务流转简单现实就是这样,下面上代码。

//实现IAbilityContinuation接口用于跨设备迁移
public class ContinuationAbility extends Ability implements IAbilityContinuation {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(ContinuationAbilitySlice.class.getName());
        requestPermissions();
    }

    //这个方法用于确定权限是否可用
    //ps:申请的权限需要在config.json里面配置
    private void requestPermissions() {
        //verifySelfPermission方法用于查询权限是否已被授权
        //这个判断!=IBundleManager.PERMISSION_GRANTED,也就是说被授权被拒绝
        if (verifySelfPermission(SystemPermission.DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
            //requestPermissionsFromUser向系统申请这个权限
            requestPermissionsFromUser(new String[] {SystemPermission.DISTRIBUTED_DATASYNC}, 0);
        }
    }

    //下面这些都是IAbilityContinuation接口的方法,目前直接实现就行
    @Override
    public boolean onStartContinuation() {
        return true;
    }

    @Override
    public boolean onSaveData(IntentParams intentParams) {
        return true;
    }

    @Override
    public boolean onRestoreData(IntentParams intentParams) {
        return true;
    }

    @Override
    public void onCompleteContinuation(int code) {
        terminateAbility();
    }

    //onRequestPermissionsFromUserResult这个方法是上面那个判断权限方法的应答接口
    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
        //如果参数不全,直接返回
        if (permissions == null || permissions.length == 0 || grantResults == null || grantResults.length == 0) {
            return;
        }
        //如果被拒绝,销毁当前ability
        if (requestCode == 0) {
            if (grantResults[0] == IBundleManager.PERMISSION_DENIED) {
                terminateAbility();
            }
        }
    }
}

首先要做这个功能需要先实现 IAbilityContinuation 接口。
这个 Ability 里,一上来需要判断权限,调用了方法requestPermissions判断。
判断后通过onRequestPermissionsFromUserResult方法进行响应。
PS:细节都写到了注释里。

这个 Ability 对应的页面是:ContinuationAbilitySlice。
我们看一下它里面的方法:

private void initComponents() {
        //点击后调用下面的migrateAbility方法
        findComponentById(ResourceTable.Id_continue_button).setClickedListener(this::migrateAbility);
        messageTextField = (TextField) findComponentById(ResourceTable.Id_message_textfield);
        //如果两个信息都不为空,为text设置信息
        if (isContinued && message != null) {
            messageTextField.setText(message);
        }
    }


    private void migrateAbility(Component component) {
        //从文本框里获取信息
        String messageSend = messageTextField.getText();
        //如果文本框是空的,弹toast提示
        if (messageSend.isEmpty()) {
            new ToastDialog(this).setText("Message can not be null").show();
            return;
        }

        try {
            //这个方法是把当前ability从当前设备流转到另一个设备上
            continueAbility();
        } catch (IllegalStateException illegalStateException) {
            HiLog.error(LABEL_LOG, "%{public}s", "migrateAbility: IllegalStateException");
        }
    }

    @Override
    public boolean onStartContinuation() {
        return true;
    }

    @Override
    //流转先保存当前信息
    public boolean onSaveData(IntentParams intentParams) {
        intentParams.setParam(MESSAGE_KEY, messageTextField.getText());
        return true;
    }

    @Override
    //然后恢复日志,之后再调用onStartContinuation
    public boolean onRestoreData(IntentParams intentParams) {
        if (intentParams.getParam(MESSAGE_KEY) instanceof String) {
            message = (String) intentParams.getParam(MESSAGE_KEY);
            isContinued = true;
        }
        return true;
    }

    @Override
    //流转完成后关闭本端ability
    public void onCompleteContinuation(int code) {
        terminate();
    }

流程是,先在当前端保存当前业务数据,然后在目标端恢复业务数据。
开发这个功能直接覆盖父类方法就可以,很简单。
这个 Demo 到此结束。


↙↙↙阅读原文可查看相关链接,并与作者交流