android、ios都没有的混合JS和Java实现页面控制

原创
06/21 21:51
阅读数 5.6K

背景

我们都知道前端开发中论开发效率,用类似小程序的开发效率要高于Android和IOS,因为小程序采用了H5的设计思想,采用Html5标签、CSS做页面布局和样式,JS控制逻辑和交互,H5的编写页面效率要远远高于Android和IOS,因此现代很多APP都采用了WebView方式的混合开发模式,通过H5实现页面,再通过JavaScript桥接方式实现调用到原生的方式。有没有不通过WebVIew的方式呢?经过我摸索,鸿蒙的交互设计真是强大,不仅能实现WebView的方式,还可以通过JSFA 调用 JAVAPA 拉起 JAVAFA,这样我们就可以轻松实现用JS Page方式实现UI,然后通过JS调用到Java中,在Java中再启动JS Page实现页面的流转。

实现的例子效果

现在我们就实现一个这样的例子:通过JS Page实现一个页面样式,然后点击页面中的一个按钮,再次启动一个 JS Page,在启动的JS Page中 在通过鸿蒙提供的router 更换页面。如下图:

实现步骤

(1)我们整体工程是在鸿蒙的Demo代码修改的。我们新建立工程,导入UI下面的JsAppDemo,如下图: (2) 先建立第2个JS page MainAbility2,最后会多出一个与default 并列的文件夹default2。在工程中的文件夹点击鼠标右键操作如图: (3)建立第三个页面,在default2下面,点击鼠标右键建立一个新页面page3,操作如下图: (4)建立MiddleAbility,主要用来实现JS调用到JAVA,这个文件是个服务Ability,操作如图: ,修改后 代码如下:

package ohos.samples.jsapplication;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.rpc.IRemoteObject;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.app.Context;
import ohos.rpc.*;
import java.io.OutputStream;
import java.net.Socket;
public class MiddleAbility extends Ability {
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
    private static final int OPEN_NEWPAGE = 1001;
    private MiddleAbility.MideleRemote mideleRemote;
    @Override
    public void onStart(Intent intent) {
        HiLog.error(LABEL_LOG, "MiddleAbility::onStart");
        super.onStart(intent);
    }

    @Override
    public void onBackground() {
        super.onBackground();
        HiLog.info(LABEL_LOG, "MiddleAbility::onBackground");
    }

    @Override
    public void onStop() {
        super.onStop();
        HiLog.info(LABEL_LOG, "MiddleAbility::onStop");
    }

    @Override
    public void onCommand(Intent intent, boolean restart, int startId) {
    }

    @Override
    public IRemoteObject onConnect(Intent intent) {

        Context context = getContext();
        mideleRemote = new MiddleAbility.MideleRemote(context);
        return mideleRemote.asObject();
    }

    @Override
    public void onDisconnect(Intent intent) {
    }
    class MideleRemote extends RemoteObject implements IRemoteBroker {

        private Context context;
        private Socket socket = null;
        private OutputStream os = null;

        public MideleRemote(Context context) {
            super("MideleRemote");
            this.context = context;
        }

        @Override
        public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) throws RemoteException {
            switch (code) {
                case OPEN_NEWPAGE:{
                    System.out.println("开启页面2");
                    //主要代码
                    Intent intent = new Intent();
                    Operation operation = new Intent.OperationBuilder().withBundleName(getBundleName())
                            .withAbilityName(MainAbility2.class.getName()).build();
                    intent.setOperation(operation);
                    startAbility(intent);

                    //主要代码

                    break;
                }
                default: {
                    reply.writeString("service not defined");
                    return false;
                }
            }
            return true;
        }

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

(5)修改Demo 中的js文件夹下的index.js 内容为:

/*
 * 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.
 */
export const MiddleAbility = {
    openNewPage: async function(){
        var actionData = {};
        var action = {};
        action.bundleName = 'ohos.samples.jsapplication';
        action.abilityName = 'ohos.samples.jsapplication.MiddleAbility';
        action.messageCode = 1001;
        action.data = actionData;
        action.abilityType = 0;
        action.syncOption = 0;
        var result = await FeatureAbility.callAbility(action);
        var ret = JSON.parse(result);
        if (ret.code == 0) {
            console.log(ret);
        } else {
            console.error(JSON.stringify(ret.code));
        }
    }
}
export default {
    data: {
        cartText: '下一步',
        cartStyle: 'cart-text',
        isCartEmpty: true,
        descriptionFirstParagraph: 'This is the merchandise page that includes fresh fruit, meat, snacks, merchandise, and more. \nYou can pick anything you like and add it to your cart. \nYour order will arrive within 48 hours. We guarantee that we are organic and healthy. \n Feel free to ask our 24-hour online service to learn more about our platforms and products.',
        imageList: ['/common/item_000.png', '/common/item_001.png', '/common/item_002.png', '/common/item_003.png'],

    },

    swipeToIndex(index) {
        this.$element('swiperImage').swipeTo({index: index});
    },


    addCart() {

        MiddleAbility.openNewPage();

    },

    getFocus() {
        if (this.isCartEmpty) {
            this.cartStyle = 'cart-text-focus';
        }
    },

    lostFocus() {
        if (this.isCartEmpty) {
            this.cartStyle = 'cart-text';
        }
    },
}

(6) 修改default2下的index.hml,index.js 实现一个按钮点击跳转。index.js代码如下:

import router from '@system.router';
export default {
    data: {
        title: ""
    },
    onInit() {
        this.title = this.$t('strings.world');
    },
    gotoNext:function (params) {

        router.push({
            uri: 'pages/page3/page3'
        });

   }
}

经过以上步骤就完成了整个功能。

特别注意:在二个步骤中MainAbility2内容一定记得增加代码: setInstanceName("default2"); 如果没有这行代码就会出现都启动的是第一个页面内容。

总结

鸿蒙的功能设计确实很周到,这样可以充分调动前端开发人员的积极性,也为混合开发提供了强大的支持,这点很让人感到惊喜,这是我一个小小的探索。
源码下载地址:https://gitee.com/zhugqiang/NBjavaHarmony/tree/master/base/mix/harmony/JsApp

展开阅读全文
打赏
0
1 收藏
分享
加载中
你好,请问用 js调用PA(ability)时,出现RemoteInterfaceProxy: connect remote interface ## fail错误,可能是什么原因啊?例如官方文档里的这个例子: https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-fa-calls-pa-examples-0000000000618000#section1341518516379
07/28 19:35
回复
举报
IT追寻者博主
你的ability 类型建立的是否是Service
前天 09:03
回复
举报
更多评论
打赏
2 评论
1 收藏
0
分享
返回顶部
顶部