HarmonyOS Sample 之 Intent 信息传递 原创 精华
@toc
Intent 信息传递
介绍
Intent 是对象之间传递信息的载体。例如,当一个 Ability 需要启动另一个 Ability 时,或者一个 AbilitySlice 需要导航到另一个 AbilitySlice 时,可以通过 Intent 指定启动的目标同时携带相关数据。
启动应用有两种方式:根据 Ability 的全称启动应用,根据 Operation 的其他属性启动应用。
本示例结合第三方登录的场景演示了如何根据Ability的全称启动应用和根据Operation的其他属性启动应用。
模拟的第三方登录的场景只是为了实践Intent 信息传递的功能,真实原理不一定是这样。
搭建环境
安装DevEco Studio,详情请参考DevEco Studio下载。
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
项目结构
该实例一共有3个应用,intent、secondapp、thirdapp
演示的效果是模拟第三方授权登录场景,使用Action和Ability的全称两种不同方式启动应用,实现不同应用之间的数据传递。
实现步骤
1.编写界面
intent的main_ability_slice.xml界面
secondapp的main_ability_slice.xml界面
thirdapp的main_ability_slice.xml界面
2.编写启动应用代码
intent应用的MainAbility.java
public class MainAbility extends Ability {
private static final HiLogLabel LABEL= new HiLogLabel(HiLog.LOG_APP,0x0001,"=>"+MainAbilitySlice.class.getName());
//商定的参数名称
private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";
private static final int REQ_CODE_START = 0;
private String ACTION_WECHAT = "action.custom.wechat";
private String ACTION_WEIBO = "action.custom.weibo";
private TextField accountTextField;
private TextField passwordTextField;
private Button loginButton;
private Text closeText;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
//使用页面组件,必须设置
super.setUIContent(ResourceTable.Layout_main_ability_slice);
initComponents();
}
private void initComponents() {
//account
accountTextField = (TextField) findComponentById(ResourceTable.Id_text_account);
//password
passwordTextField = (TextField) findComponentById(ResourceTable.Id_text_password);
//
loginButton= (Button) findComponentById(ResourceTable.Id_btn_login);
//wechat
Component component1 = findComponentById(ResourceTable.Id_start_by_wechat);
component1.setClickedListener(component -> applyWeChat());
//qq
Component component2 = findComponentById(ResourceTable.Id_start_by_qq);
component2.setClickedListener(component -> startByName());
//weibo
Component component3 = findComponentById(ResourceTable.Id_start_by_weibo);
component3.setClickedListener(component -> applyWeiBo());
//关闭
closeText = (Text) findComponentById(ResourceTable.Id_close_text);
closeText.setClickedListener(component -> terminateAbility());
}
/**
* 通过AbilityName启动应用
* startAbility 不返回数据
*/
private void startByName() {
Intent intent = new Intent();
//传递参数:申请授权方
intent.setParam("applyParty","LiveApp");
//方式一,AbilityName+bundleName
Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withBundleName("ohos.samples.secondapp")
.withAbilityName("ohos.samples.secondapp.MainAbility")
.build();
intent.setOperation(operation);
//不返回参数
//startAbility(intent);
//返回参数,和 onAbilityResult是配套使用的
startAbilityForResult(intent, REQ_CODE_START);
}
/**
* 通过ACTION启动应用
* startAbilityForResult 支持返回数据
*/
private void applyWeChat() {
Intent intent = new Intent();
//传递参数:申请授权方
intent.setParam("applyParty","LiveApp");
//方式一,AbilityName+bundleName
/* Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withBundleName("ohos.samples.secondapp")
.withAbilityName("ohos.samples.secondapp.MainAbility")
.build();*/
//方式二,Action,不用加bundleName
Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withAction(ACTION_WECHAT)
.build();
intent.setOperation(operation);
//和 onAbilityResult是配套使用的
startAbilityForResult(intent, REQ_CODE_START);
}
/**
* 通过ACTION启动应用
* startAbilityForResult 支持返回数据
*/
private void applyWeiBo() {
Intent intent = new Intent();
//传递参数:申请授权方
intent.setParam("applyParty","LiveApp");
//方式一,AbilityName+bundleName
/*Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withBundleName("ohos.samples.thirdapp")
.withAbilityName("ohos.samples.thirdapp.ThirdApplyAbility")
.build();*/
//方式二,Action,不用加bundleName
Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withAction(ACTION_WEIBO)
.build();
intent.setOperation(operation);
//和onAbilityResult是配套使用的
startAbilityForResult(intent, REQ_CODE_START);
}
@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
super.onAbilityResult(requestCode, resultCode, resultData);
HiLog.debug(LABEL,"onResult...requestCode:"+requestCode+",resultData:"+resultData);
//获取返回的数据
if (requestCode == REQ_CODE_START && resultData != null) {
accountTextField.setText(resultData.getStringParam(ACCOUNT_KEY));
passwordTextField.setText(resultData.getStringParam(PASSWORD_KEY));
}
//设置登录按钮可用
Element element= ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_button_background_actived);
loginButton.setBackground(element);
}
}
secondapp应用的MainAbility.java
public class MainAbility extends Ability {
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0xD0001, "=>" + MainAbility.class.getName());
//商定的参数名称
private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";
private Button applyButton;
private Button rejectButton;
private Text applyParty;
private Text cancel;
private String ACTION_START = "action.custom.wechat";
@Override
public void onStart(Intent intent) {
HiLog.debug(LABEL,"ability onStart...");
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
//使用页面组件,必须设置
super.setUIContent(ResourceTable.Layout_main_ability_slice);
//如果是Ability的默认slice,可以不设置
//addActionRoute(ACTION_START, MainAbilitySlice.class.getName());
//接受授权
applyButton = (Button) findComponentById(ResourceTable.Id_btn_apply);
applyButton.setClickedListener(component -> apply());
//取消授权
rejectButton = (Button) findComponentById(ResourceTable.Id_btn_reject);
rejectButton.setClickedListener(component -> terminateAbility());
//取消授权
cancel = (Text) findComponentById(ResourceTable.Id_close_text);
cancel.setClickedListener(component -> terminateAbility());
//申请授权方
applyParty = (Text) findComponentById(ResourceTable.Id_apply_party);
String applyPartyParam = intent.getStringParam("applyParty");
if (intent.hasParameter("applyParty")) {
applyParty.setText(applyPartyParam + " 申请使用");
}
}
/**
* 接受授权
*/
private void apply() {
Intent resultIntent = new Intent();
//设置返回的参数
resultIntent.setParam(ACCOUNT_KEY, "Zhangsaner");
resultIntent.setParam(PASSWORD_KEY, "zhangsaner@123");
setResult(0, resultIntent);
//关闭当前应用
terminateAbility();
}
}
secondapp应用的config.json,声明"action.custom.wechat" Action
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home",
"action.custom.wechat"
]
}
],
thirdapp应用的ThirdApplyAbility.java
public class ThirdApplyAbility extends Ability {
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0xD0011, "=>" + ThirdApplyAbility.class.getName());
//商定的参数名称
private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";
private Button applyButton;
private Text cancel;
private String ACTION_START = "action.custom.weibo";
@Override
public void onStart(Intent intent) {
HiLog.debug(LABEL, "ability onStart...");
super.onStart(intent);
super.setMainRoute(ThirdApplyAbilitySlice.class.getName());
//如果是Ability的默认slice,可以不设置
//addActionRoute(ACTION_START, ThirdApplyAbilitySlice.class.getName());
//使用页面组件,必须设置
super.setUIContent(ResourceTable.Layout_ability_third_apply);
//接受授权
applyButton = (Button) findComponentById(ResourceTable.Id_btn_apply);
applyButton.setClickedListener(component -> apply());
//取消授权
cancel = (Text) findComponentById(ResourceTable.Id_close_text);
//关闭slice
cancel.setClickedListener(component -> terminateAbility());
}
/**
* 接受授权
*/
private void apply() {
Intent resultIntent = new Intent();
//设置返回的参数
resultIntent.setParam(ACCOUNT_KEY, "xiaowei");
resultIntent.setParam(PASSWORD_KEY, "xiaowei@123");
setResult(0, resultIntent);
//关闭当前Ability
terminateAbility();
}
}
thirdapp应用的config.json,在ThirdApplyAbility的skills中声明"action.custom.weibo" Action
{
"orientation": "unspecified",
"visible": true,
"name": "ohos.samples.thirdapp.ThirdApplyAbility",
"icon": "$media:icon",
"description": "$string:thirdapplyability_description",
"label": "$string:thirdapp_ThirdApplyAbility",
"type": "page",
"launchType": "standard",
"metaData": {
"customizeData": [
{
"name": "hwc-theme",
"value": "androidhwext:style/Theme.Emui.Light.NoTitleBar"
}
]
},
"skills": [
{
"actions": [
"action.custom.weibo"
]
}
]
}
问题总结
1.如果在Ability中要使用Slice的组件,需要设置UIContent,否则会找不到组件
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
//如果在Ability中使用页面组件,需要设置UIContent
super.setUIContent(ResourceTable.Layout_main_ability_slice);
initComponents();
}
2.使用Actin方式,需要在config.json 对应的Ability中声明路由
是否需要在对应Ability的onStart方法中addActionRoute添加设置,要看路由指向的是不是Ability默认的Slice
3.使用Action方式,需要在Operation中指定Action,使用Ability的全称方式需要在Operation中指定AbilityName+bundleName
//方式一,AbilityName+bundleName
/*Operation operation = new Intent.OperationBuilder().withDeviceId("")
//必须设置
.withBundleName("ohos.samples.thirdapp")
//可以带bundleName,也可以不带
.withAbilityName("ThirdApplyAbility")
.build();*/
//方式二,Action,不用加bundleName
Operation operation = new Intent.OperationBuilder().withDeviceId("")
.withAction(ACTION_WEIBO)
.build();
效果展示
完整代码
附件直接下载