JAVA_TO_JS_ABILITY.md 7.4 KB

Java Ability 调用 JS Ability 完整示例

📋 概述

本示例展示了在 HarmonyOS Java API 7 项目中,如何从 Java Ability 调用 JS Ability 的多种方式。

🎯 使用场景

  • 从 Java Ability 跳转到 JS 页面
  • Java 和 JS 之间传递数据
  • JS Ability 返回结果给 Java Ability
  • 跨语言混合开发

📂 文件结构

entry/src/main/
├── java/com/fujica/abk/
│   ├── utils/
│   │   └── JsAbilityHelper.java          # 工具类
│   └── slice/
│       └── JsAbilityDemoSlice.java       # 演示示例
├── js/jsability/
│   └── pages/index/
│       ├── index.hml                     # JS 页面结构
│       ├── index.css                     # JS 页面样式
│       └── index.js                      # JS 页面逻辑
└── config.json                           # 配置文件

🚀 使用方法

方式一:简单启动(不需要返回结果)

JsAbilityHelper.startJsAbility(
    getAbility(),                         // 当前 Ability
    "com.fujica.abk",                     // 应用包名
    "com.fujica.abk.JsAbility",          // JS Ability 名称
    "来自 Java 的问候",                   // 消息参数
    "这是传递的数据"                      // 数据参数
);

方式二:启动并等待返回结果

JsAbilityHelper.startJsAbilityForResult(
    getAbility(),
    "com.fujica.abk",
    "com.fujica.abk.JsAbility",
    "请返回数据",
    "Request ID: 12345"
);

// 在 Ability 中重写 onAbilityResult 方法接收返回结果
@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
    super.onAbilityResult(requestCode, resultCode, resultData);
    
    if (requestCode == JsAbilityHelper.getRequestCode()) {
        if (resultData != null) {
            String status = resultData.getStringParam("status");
            String data = resultData.getStringParam("data");
            // 处理返回的数据
        }
    }
}

方式三:从 AbilitySlice 启动

JsAbilityHelper.startJsAbilityFromSlice(
    this,                                 // 当前 AbilitySlice
    "com.fujica.abk",
    "com.fujica.abk.JsAbility",
    "从 Slice 发送",
    "Slice 数据"
);

方式四:传递 JSON 复杂对象

// 创建 JSON 对象
ZSONObject jsonData = new ZSONObject();
jsonData.put("userId", "123456");
jsonData.put("userName", "张三");
jsonData.put("action", "query");
jsonData.put("timestamp", System.currentTimeMillis());

JsAbilityHelper.startJsAbilityWithJson(
    getAbility(),
    "com.fujica.abk",
    "com.fujica.abk.JsAbility",
    jsonData
);

📥 JS Ability 接收参数

在 JS 端的 index.js 中:

import featureAbility from '@ohos.ability.featureAbility';

export default {
    data: {
        receivedData: '无'
    },
    
    onInit() {
        // 获取从 Java 传递过来的参数
        var context = featureAbility.getContext();
        context.getWant((error, want) => {
            if (!error && want.parameters) {
                var dataFromJava = want.parameters.data;
                var messageFromJava = want.parameters.message;
                
                this.receivedData = dataFromJava;
                console.info('接收到的数据: ' + dataFromJava);
            }
        });
    }
}

📤 JS Ability 返回数据

在 JS 端返回数据并关闭页面:

import featureAbility from '@ohos.ability.featureAbility';

// 返回数据给 Java
returnData() {
    var result = {
        resultCode: 1,
        want: {
            parameters: {
                status: 'success',
                data: 'JS 返回的数据',
                timestamp: new Date().getTime()
            }
        }
    };
    
    var context = featureAbility.getContext();
    context.terminateSelfWithResult(result, (error) => {
        if (!error) {
            console.info('成功返回数据');
        }
    });
}

⚙️ config.json 配置

需要在 config.json 中注册 JS Ability:

{
  "module": {
    "abilities": [
      {
        "name": ".JsAbility",
        "srcPath": "jsability",
        "icon": "$media:icon",
        "description": "JS Ability 示例",
        "label": "JS Ability",
        "type": "page",
        "visible": true,
        "launchType": "standard"
      }
    ],
    "js": [
      {
        "name": "jsability",
        "pages": [
          "pages/index/index"
        ],
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        }
      }
    ]
  }
}

🔧 测试方法

  1. 在 MainAbility 中添加 Slice
public class MainAbility extends Ability {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(JsAbilityDemoSlice.class.getName());
    }
}
  1. 运行应用,点击不同按钮测试各种调用方式

  2. 查看日志

    hdc_std shell hilog | grep JsAbility
    

    📝 注意事项

    1. 包名和 Ability 名称必须正确
    2. 包名:com.fujica.abk
    3. JS Ability 完整名称:com.fujica.abk.JsAbility

    4. JS Ability 必须在 config.json 中正确注册

    5. abilities 数组中添加 Ability 配置

    6. js 数组中添加 JS 页面配置

    7. 参数传递限制

    8. 基本类型:String, int, long, boolean 等

    9. 复杂对象需要转换为 JSON 字符串

    10. 返回结果处理

    11. 只有使用 startAbilityForResult 才能接收返回结果

    12. 必须在 Ability 中重写 onAbilityResult 方法

    13. 线程安全

    14. Ability 启动操作在主线程执行

    15. 耗时操作应放在子线程

    🎨 自定义扩展

    添加更多参数类型

    intent.setParam("stringParam", "字符串");
    intent.setParam("intParam", 123);
    intent.setParam("longParam", 123456789L);
    intent.setParam("booleanParam", true);
    intent.setParam("doubleParam", 3.14);
    

传递数组

String[] array = {"item1", "item2", "item3"};
intent.setParam("arrayParam", array);

传递序列化对象

// 自定义对象需要实现 Sequenceable 接口
MyData myData = new MyData();
intent.setParam("objectParam", myData);

🐛 常见问题

1. JS Ability 无法启动

原因:包名或 Ability 名称错误

解决:检查 config.json 中的配置和调用代码中的名称是否一致

2. 参数无法传递

原因:参数类型不支持或 JS 端未正确获取

解决:使用支持的基本类型,或将复杂对象转为 JSON 字符串

3. 无法接收返回结果

原因:使用了 startAbility 而不是 startAbilityForResult

解决:使用 startAbilityForResult 并实现 onAbilityResult 方法

4. JS 端获取不到参数

原因:参数获取时机不对或方法使用错误

解决:在 onInitonShow 中使用 featureAbility.getContext().getWant() 获取

📚 相关资源

📄 许可证

本示例代码遵循项目原有许可证。