從微信小程序到鴻蒙js開發【15】——JS調用Java


鴻蒙入門指南,小白速來!0基礎學習路線分享,高效學習方法,重點答疑解惑--->【課程入口】

目錄:
1、新建一個Service Ability
2、完善代碼邏輯
3、JS端遠程調用
4、《從微信小程序到鴻蒙js開發》系列文章合集

除輕量級智能穿戴設備,現鴻蒙支持的手機、汽車、TV、手表、平板等屬於富鴻蒙,在JS語言的項目中也有Java模塊,並提供了JS跨語言調用Java方法的技術。現需要實現查看商品評論時,統計出長評、中評和短評的比例,這里將評論數據請求來后調用Java進行計算。

JS調用Java有Ability方式和Internal Ability方式兩種,前者可以被不同的JS方法調用,后者適用於與JS業務邏輯關聯性強,響應時延要求高的服務。這里采用Ability的方式。

1、新建一個Service Ability

在項目工程目錄Java模塊中,右鍵項目的包,New->Ability->Empty Service Ability。

從微信小程序到鴻蒙js開發【15】——JS調用Java

在自動生成的眾多重載方法中,我們需要用到的是onConnect()。此方法在首次連接時回調,並返回IRemoteObject對象,用於后續的業務通信。

因此創建一個內部類,繼承RemoteObject類並實現IRemoteBroker接口。代碼框架如下:

public class ServiceAbility extends Ability {

    private MyRemote remote = new MyRemote();

    @Override
    public IRemoteObject onConnect(Intent intent) {
        super.onConnect(intent);
        return remote.asObject();
    }

    static class MyRemote extends RemoteObject implements IRemoteBroker {

        MyRemote() {
            super("MyService_MyRemote");
        }

        MyRemote(String descriptor) {
            super(descriptor);
        }

        @Override
        public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
            ......
        }

        @Override
        public IRemoteObject asObject() {
            return this;
        }
    }

}

主要需實現的兩個方法是onRemoteRequest()和asObject()。在onConnect()方法中返回內部類的示例,asObject()直接返回this即可。onRemoteRequest()是主要需要實現的業務方法,有四個參數:

  • code:JS端請求時帶來的請求碼,可根據code進行不同的業務處理。
  • data:JS端請求時帶來的數據,目前僅支持json格式。Java端通過data.readString()獲取請求json字符串。
  • reply:Java端返回給JS端的數據,目前僅支持String格式,通過reply.writeString(str)寫入返回數據。
  • option:JS端指定同步或異步方式,Java端通過option.getFlag()獲取。

2、完善代碼邏輯

規定JS端每分頁加載一次評論數據,就將目前頁面中的所有評論內容發送給Java端進行計算。流程和HTTP有一點類似,獲取數據、處理數據、返回數據。鴻蒙提供了ZSONObject可供處理json,完整邏輯代碼如下:

public class ServiceAbility extends Ability {

    private MyRemote remote = new MyRemote();

    @Override
    public IRemoteObject onConnect(Intent intent) {
        super.onConnect(intent);
        return remote.asObject();
    }

    static class MyRemote extends RemoteObject implements IRemoteBroker {

        private static final int LIST_COMMENTS = 200;
        private static final int SUCCESS = 0;
        private static final int ERROR = 500;

        MyRemote() {
            super("MyService_MyRemote");
        }

        MyRemote(String descriptor) {
            super(descriptor);
        }

        @Override
        public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
            Map<String, Object> result = new HashMap<>(5);
            if (code == LIST_COMMENTS) {
                // 獲取並轉化請求數據
                String req = data.readString();
                WordReq param = ZSONObject.stringToClass(req, WordReq.class);
                List<String> comments = param.getList().stream().filter(e -> !"用戶未填寫評價內容".equals(e)).collect(Collectors.toList());
                // 統計評論字數
                int longComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 200).count();
                int mediumComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 30 && len < 200).count();
                int shortComments = (int) comments.stream().mapToInt(String::length).filter(len -> len < 30).count();
                // 計算占比
                DecimalFormat df = new DecimalFormat("#.00");
                double longPer = 1.0 * longComments / comments.size() * 100;
                double mediumPer = 1.0 * mediumComments / comments.size() * 100;
                double shortPer = 1.0 * shortComments / comments.size() * 100;
                // 返回結果
                result.put("long", df.format(longPer) + "%");
                result.put("medium", df.format(mediumPer) + "%");
                result.put("short", df.format(shortPer) + "%");
                result.put("code", SUCCESS);
                result.put("msg", "ok");
                reply.writeString(ZSONObject.toZSONString(result));
                return true;
            } else {
                result.put("code", ERROR);
                result.put("msg", "invalid code");
                reply.writeString(ZSONObject.toZSONString(result));
                return false;
            }
        }

        @Override
        public IRemoteObject asObject() {
            return this;
        }
    }

}

3、JS端遠程調用

Java服務部分寫好了,在JS中,鴻蒙提供了FeatureAbility.callAbility()方法用於單次請求Java服務。其參數如下:

  • bundleName:Ability包名,在config.json中,為app.bundleName。
  • abilityName:調用服務端Ability類名,可省略包名,直接寫".XxxAbility"。
  • messageCode:操作碼,和Java端的"code"參數相匹配。
  • abilityType:Ability類型,0為Ability,1為Internal Ability。
  • data:請求數據,json類型。
  • syncOption:與Java端"option"相匹配,0為同步方式,1為異步方式。默認同步方式。

    方法返回一個Promise對象,可通過.then()和.catch()處理調用成功和異常。

本例中的方法如下:

// 調用Java統計評論長度
    countWords() {
        let list = [];
        this.comments.forEach(e => {
            list.push(e.content);
        })
        FeatureAbility.callAbility({
            bundleName: "com.example.litemall",
            abilityName: ".ServiceAbility",
            messageCode: 200,
            abilityType: 0,
            data: {
                list
            }
        }).then(res => {
            console.info(res);
            let data = JSON.parse(res);
            if (data.code == 0) {
                this.lengths[0].value = data.long;
                this.lengths[1].value = data.medium;
                this.lengths[2].value = data.short;
            }
        }).catch(res => {
            console.error(res);
        })
    }

Java端和JS端的代碼編譯完成並運行,可以看到日志中的返回數據和我們在Java中定義的一致。

從微信小程序到鴻蒙js開發【15】——JS調用Java

運行效果:從微信小程序到鴻蒙js開發【15】——JS調用Java

從微信小程序到鴻蒙js開發【15】——JS調用Java

但加上Java的部分后,項目編譯的速度明顯變慢了,如下兩步花了很長時間,有沒有大神知道有沒有什么加速的方法?

從微信小程序到鴻蒙js開發【15】——JS調用Java從微信小程序到鴻蒙js開發【15】——JS調用Java

作者:Chris.
想了解更多內容,請訪問: 51CTO和華為官方戰略合作共建的鴻蒙技術社區https://harmonyos.51cto.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM