IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Uniapp 原生插件开发

    obaby发表于 2024-05-31 02:30:32
    love 0

    自从用了 uniapp 之后,腿不酸了,腰不疼了,一口气爬五楼不费劲了。但是,uniapp 虽好,也有解决不了的问题。用了好多好多天的功夫终于调通了 unipush,能够将消息推送到华为手机上了。

    然鹅,消息推送下来之后,系统会自动增加桌面图标的角标数字。然后每收到一条消息这个就会+1,再之后,就看到这个数字不断的增加。uni 官方提供了设置角标的api:

    plus.runtime.setBadgeNumber(3);

    看起来简单粗暴,人畜无害。实际效果呢,就是 iOS 系统上成功了,最起码这个是有效果的,然而再安卓系统上就芭比了。啥用都没有,不过这个倒是也不算出乎意料。

    安卓系统的角标设置,简单来说分为两类,一种是标准的,所谓标准就是 google 的原生框架,可以通过原生接口实现,例如 Android Oreo 及以上版本的 Notification Badges。

    另外一种就是国情货了,例如各种国产品牌,这些厂商的角标设置本质上是对各个厂商的 launcher 的适配,每个厂商的启动器都不一样。所以就只能通过原生的办法来解决,至于如何解决这个问题,会在后面的文章中写。

    上述的这些功能的实现 uni 是解决不了的,就只能通过原生来实现了。此时就需要开发 uni 的原生语言插件,这个插件的本质就是安卓的 module 组件。

    创建插件项目最简单的方法就是直接下载官方的 sdk,然后导入示例项目,直接在示例项目上修改或者新建。uni 的官方 sdk 可以通过下面的链接下载:

    https://nativesupport.dcloud.net.cn/AppDocs/download/android.html

    直接导入 as 工程即可浏览相关的代码和组件。

    当然,也可以直接创建一个新的项目,可以参考下面的步骤(前提是已经安装好 android studio,如果还没安装,先去找别的文章看看怎么安装哈):

    1.新建安卓项目这个随便选择即可,主要是用于测试一些功能代码:

    2.新建 module

    3.修改 module 的build.gradle 添加必要的依赖

    主要是下面几行:

    compileOnly 'com.alibaba:fastjson:1.2.83'
    compileOnly fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
    api project(':launcherBadge') # 其他项目依赖,如果没有可以不添加

    4.复制 sdk 下的uniapp-v8-release.aar 到 module 的 libs 目录下:

    5.编写 module 代码,测试代码如下:

    package cn.org.obaby.badge;
    
    import android.content.Context;
    import android.os.Handler;
    import android.util.Log;
    
    import com.alibaba.fastjson.JSONObject;
    
    import io.dcloud.feature.uniapp.annotation.UniJSMethod;
    import io.dcloud.feature.uniapp.bridge.UniJSCallback;
    import io.dcloud.feature.uniapp.common.UniModule;
    
    public class babyBadgeModule extends UniModule{
        private static final String TAG = "badgeModule";
        public static  final String Name = "hello world";
        public void testLoad(){
            Log.i("test", "hello");
        }
        //run ui thread
        @UniJSMethod(uiThread = true)
        public void testAsyncFunc(JSONObject options, UniJSCallback callback) {
    //        Log.e(TAG, "testAsyncFunc--"+options);
            if(callback != null) {
                JSONObject data = new JSONObject();
                data.put("code", "success");
                callback.invoke(data);
            }
        }
    
        //run JS thread
        @UniJSMethod (uiThread = false)
        public JSONObject testSyncFunc(){
            JSONObject data = new JSONObject();
            data.put("code", "success");
            return data;
        }
    }

    注意要 import uni相关的类:

    import com.alibaba.fastjson.JSONObject;
    
    import io.dcloud.feature.uniapp.annotation.UniJSMethod;
    import io.dcloud.feature.uniapp.bridge.UniJSCallback;
    import io.dcloud.feature.uniapp.common.UniModule;

    另外 module 要继承自UniModule,如果是Component 扩展类必须继承 UniComponent, 父容器Component(例如ViewGroup组件)则需要继承UniVContainer,具体参考官方教程:https://nativesupport.dcloud.net.cn/NativePlugin/course/android.html

    6.编译组件:

    菜单 build->build module

    此时就会在 build 目录下生成对应的 aar 文件了。

    7.在 uniapp 目录nativeplugins下新建插件目录babyBadgeModule(如果没有nativeplugins目录,创建即可):

    在插件根目录babyBadgeModule 下新建文件夹 android,以及文件 package.json(注意文件名,这个文件名不知道是复制错了,还是写错了,导致 uni 一直识别不到插件,崩溃。)

    将生成的 aar 文件放入 android 目录下。

    package.json 文件内容:

    {
        "name": "babyBadgeModule",
        "id": "babyBadgeModule", 
        "version": "1.0.1",
        "description": "Android 角标插件",
        "_dp_type":"nativeplugin",
        "_dp_nativeplugin":{
            "android": {
                "plugins": [
                    {
                        "type": "module",
                        "name": "babyBadgeModule",
                        "class": "cn.org.obaby.badge.babyBadgeModule"
                    }
                ],
                "integrateType": "aar",
                "minSdkVersion" : 21
            }
        }
    }

    8.选择本地插件

    9.uni 代码实现,调用原生插件(下面的代码,调用了两个原生组件):

    const babyBadgeModule = uni.requireNativePlugin('babyBadgeModule');
                console.log(babyBadgeModule)
                babyBadgeModule.setLauncherBadgeCount({COUNT:3},result => {this.showToast('test')});
                // require插件名称
                const dcRichAlert = uni.requireNativePlugin('DCloud-RichAlert');
                // 使用插件
                dcRichAlert.show({
                    position: 'bottom',
                    title: "提示信息",
                    titleColor: '#FF0000',
                    content: "<a href='https://uniapp.dcloud.io/' value='Hello uni-app'>uni-app</a> 是一个使用 Vue.js 开发跨平台应用的前端框架!\n免费的\n免费的\n免费的\n重要的事情说三遍",
                    contentAlign: 'left',
                    checkBox: {
                        title: '不再提示',
                        isSelected: true
                    },
                    buttons: [{
                        title: '取消'
                    },
                    {
                        title: '否'
                    },
                    {
                        title: '确认',
                        titleColor: '#3F51B5'
                    }
                    ]
                }, result => {
                    switch (result.type) {
                        case 'button':
                            console.log("callback---button--" + result.index);
                            break;
                        case 'checkBox':
                            console.log("callback---checkBox--" + result.isSelected);
                            break;
                        case 'a':
                            console.log("callback---a--" + JSON.stringify(result));
                            break;
                        case 'backCancel':
                            console.log("callback---backCancel--");
                            break;
                   }
                });

     

    10.打自定义基座包:

    11.打包完成之后就可以真机调试了,不过如果遇到下面的错误可以尝试将插件名称、目录、id 之类的全部同意再次尝试:

    应用【闺蜜圈】已启动
    09:00:26.335 [JS Framework] 当前运行的基座不包含原生插件[Baby-Badge],请在manifest中配置该插件,重新制作包括该原生插件的自定义运行基座
    09:00:26.364 undefined  at pages/index.vue:583
    09:00:26.365 [Vue warn]: Error in onLoad hook: "TypeError: Cannot read property 'setLauncherBadgeCount' of undefined"
    
    (found at pages/index.vue:1)
    09:00:26.365 TypeError: Cannot read property 'setLauncherBadgeCount' of undefined

    本质上还是插件目录以及文件内容导致的错误,多检查一致性吧,这个确实没什么好办法。

    至于调试,再设备上不好调试,可以再原生组件添加 log,通过 logcat 查看相关的日志。至此插件就基本可以用了:



沪ICP备19023445号-2号
友情链接