DCloud_Android_ST
DCloud_Android_ST
  • 发布:2020-02-25 17:27
  • 更新:2024-10-11 12:26
  • 阅读:7153

Android 扩展 uni小程序SDK 原生能力

分类:uni小程序sdk

Android 扩展 uni小程序SDK 原生能力

概述

本文档主要介绍如何扩展 uni小程序SDK 原生能力。

什么是扩展原生能力?

扩展原生能力指的是将您原生开发的功能通过一定规范暴露给 uni小程序环境,然后即可在 uni小程序应用中调用您的原生功能。

扩展方式

uni 原生端是基于 WeexSDK 来实现扩展原生能力,扩展原生能力有两种方式:一种是不需要参与页面布局,只需要通过 API 调用原生功能,比如:获取当前定位信息、数据请求等功能,这种情况可通过扩展module的方式来实现;另一种是需要参与页面布局,比如:map、image,这种情况需要通过扩展component即组件的方法来实现;

开发前准备

注意事项

如果你扩展的ModuleComponent要与宿主进行数据交互需要注意。宿主与小程序不在同一进程,内存不共享。所以需要开发者自己实现跨进程通信。后续会完善此交互问题。

关于扩展的ModuleComponent代码中日志log。小程序运行在io.dcloud.unimp子进程。看日志log需要在这个进程看日志log。

扩展 module

下面以TestModule为例,源码请查看 uni小程序SDK 包中的示例 DEMO 工程;

1.创建Android Studio的Module模块

  • 在现有Android项目中创建library的Module。例如TestModule
  • 配置刚创建的Module的build.gradle信息。

    示例:

    //导入aar需要的配置  
    repositories {  
        flatDir {  
            dirs 'libs'  
        }  
    }  
    dependencies {  
        //必须添加的依赖  
        compileOnly 'com.android.support:recyclerview-v7:27.1.0'  
        compileOnly 'com.android.support:support-v4:27.1.0'  
        compileOnly 'com.android.support:appcompat-v7:27.1.0'  
        compileOnly 'com.alibaba:fastjson:1.1.46.android'  
    
        compileOnly fileTree(include: ['uniapp-release.aar'], dir: '../app/libs')  
    }  

    Tips:

    uniapp-release.aar是扩展module主要依赖库,必须导入此依赖库!

2.创建TestModule类

  • Module 扩展必须继承 WXModule 类

    示例:

    public class TestModule extends WXModule  
  • 扩展方法必须加上@JSMethod (uiThread = false or true) 注解。Weex 会根据注解来判断当前方法是否要运行在 UI 线程,和当前方法是否是扩展方法。

  • Weex是根据反射来进行调用 Module 扩展方法,所以Module中的扩展方法必须是 public 类型。

    示例:

    //run ui thread  
    @JSMethod(uiThread = true)  
    public void testAsyncFunc(JSONObject options, JSCallback callback) {  
        Log.e(TAG, "testAsyncFunc--"+options);  
        if(callback != null) {  
            JSONObject data = new JSONObject();  
            data.put("code", "success");  
            callback.invoke(data);  
        }  
    }  
    
    //run JS thread  
    @JSMethod (uiThread = false)  
    public JSONObject testSyncFunc(){  
        JSONObject data = new JSONObject();  
        data.put("code", "success");  
        return data;  
    }  
  • 同样因为是通过反射调用,Module 不能被混淆。请在混淆文件中添加代码:-keep public class extends com.taobao.weex.common.WXModule{;}

  • Module 扩展的方法可以使用 int, double, float, String, Map, List 类型的参数

3.注册TestModule

由于uni小程序运行在独立子进程中。内存与宿主不共享。所以宿主进程注册了TestModule,在uni小程序是无法使用的。
Android创建子进程时会主动再次初始化Application!所以uni小程序注册TestModule必须在Application中的onCreate初始化或注册。

Tips

  • 注册TestModule之前记得配置宿主的build.gradle导入Module模块.
  • 以下示例代码写在宿主的Application中。

示例:

public class App extends Application {  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        try {  
            WXSDKEngine.registerModule("TestModule", TestModule.class);  
        } catch (WXException e) {  
            e.printStackTrace();  
        }  
    }  
}

到此,我们已经完成了一个简单的 module 扩展

4. 在 uni小程序 中调用 module 方法

module 支持在 vue 和 nvue 中使用

示例:

<template>  
    <div>  
        <button type="primary" @click="testAsyncFunc">testAsyncFunc</button>  
        <button type="primary" @click="testSyncFunc">testSyncFunc</button>  
    </div>  
</template>  

<script>  
    // 获取 module   
    var testModule = uni.requireNativePlugin("TestModule")  
    export default {  
        methods: {  
            testAsyncFunc() {  
                // 调用异步方法  
                testModule.testAsyncFunc({  
                        'name': 'unimp',  
                        'age': 1  
                    },  
                    (ret) => {  
                        console.log(ret)  
                    })  
            },  
            testSyncFunc() {  
                // 调用同步方法  
                var ret = testModule.testSyncFunc({  
                    'name': 'unimp',  
                    'age': 1  
                })  
                console.log(ret)  
            }  
        }  
    }  
</script>  

扩展组件 component

下面以TestComponent为例,源码请查看 uni小程序SDK 包中的示例 DEMO 工程;

1.创建Android Studio的Module模块

请参考 扩展 Module

2.创建TestComponent类

  • Component 扩展类必须继承 WXComponent

    示例:

    public class TestText extends WXComponent<TextView>  
  • WXComponent的initComponentHostView回调函数。构建Component的view时会触发此回调函数。

    示例:

    @Override  
    protected TextView initComponentHostView(@NonNull Context context) {  
        TextView textView = new TextView(context);  
        textView.setTextSize(20);  
        textView.setTextColor(Color.BLACK);  
        return textView;  
    }  
  • Component 对应的设置属性的方法必须添加注解 @WXComponentProp(name=value(value is attr or style of dsl))

    示例:

    @WXComponentProp(name = "tel")  
    public void setTel(String telNumber) {  
        getHostView().setText("tel: " + telNumber);  
    }  
  • Weex sdk 通过反射调用对应的方法,所以 Component 对应的属性方法必须是 public,并且不能被混淆。请在混淆文件中添加代码 -keep public class extends com.taobao.weex.ui.component.WXComponent{;}

  • Component 扩展的方法可以使用 int, double, float, String, Map, List 类型的参数

  • Component 自定义事件
    对于每个组件默认提供了一些事件能力,如点击等。也可以自定义事件。在uni小程序代码中,通过 @事件名="方法名" 添加事件,如下添加onTel事件

    //原生触发fireEvent 自定义事件onTel  
    Map<String, Object> params = new HashMap<>();  
    Map<String, Object> number = new HashMap<>();  
    number.put("tel", telNumber);  
    //目前uni限制 参数需要放入到"detail"中 否则会被清理  
    params.put("detail", number);  
    fireEvent("onTel", params);  
    
    //标签注册接收onTel事件  
    <myText tel="12305" style="width:200;height:100" @onTel="onTel"></myText>  
    //事件回调  
    methods: {    
        onTel: (e)=> {  
            console.log("onTel="+e.detail.tel);  
        }  
    }    

    注意

    执行自定义事件fireEvent时params的数据资源都要放入到"detail"中。如果没有将你得返回的数据放入"detail"中将可能丢失。请注意!!!

3.注册TestComponent组件

由于uni小程序运行在独立子进程中。内存与宿主不共享。所以宿主进程注册了TestComponent,在uni小程序是无法使用的。
Android创建子进程时会主动再次初始化Application!所以uni小程序注册TestComponent必须在Application中的onCreate初始化或注册。

Tips

  • 注册TestModule之前记得配置宿主的build.gradle导入的Module模块.
  • 以下示例代码写在宿主的Application中。

示例:

public class App extends Application {  

    @Override  
    public void onCreate() {  
        try {  
            WXSDKEngine.registerComponent("myText", TestText.class);  
        } catch (WXException e) {  
            e.printStackTrace();  
        }  
        super.onCreate();  
    }  
}

到此,我们已经完成了一个简单的 component 扩展

4. 在uni小程序代码中使用组件

注意:扩展的 component 只能在 nvue 文件中使用

示例:

<template>  
    <div>  
        <myText tel="12305" style="width:200;height:100" @onTel="onTel"></myText>  
    </div>  
</template>  

<script>    
    export default {    
        data() {    
            return {    
            }    
        },    
        onLoad() {    
        },    
        methods: {    
            onTel: (e)=> {  
                console.log("onTel="+e.detail.tel);  
            }  
        }    
    }    
</script>

Android 扩展开发小提示

查看Android原生日志

小程序运行在独立子进程。所以想要看小程序的日志需要将进程切换到io.dcloud.unimp进程查看log!

查看小程序 console日志

修改项目中assets/data/dcloud_control.xml 内部信息。将syncDebug改为true,开启调试模式。 注意正式版需要改为false!!!
修改后查看io.dcloud.unimp进程查看log。TAG为console

在WXModule、WXComponent中跳转原生页面

获取WXSDKInstance对象。该对象中可以获取到上下文。

示例

@JSMethod (uiThread = true)  
public void gotoNativePage(){  
    if(mWXSDKInstance != null) {  
        Intent intent = new Intent(mWXSDKInstance.getContext(), NativePageActivity.class);  
        mWXSDKInstance.getContext().startActivity(intent);  
    }  
}
0 关注 分享

要回复文章请先登录注册

1***@163.com

1***@163.com

uniapp x 如何像安卓原生这样注册插件给uni 小程序用?
2024-10-11 12:26
小金家的沐沐

小金家的沐沐

关于日志,可以通过Weex提供的日志拦截方法。不用去从js到java层调用。

WXLogUtils.setJsLogWatcher(new WXLogUtils.JsLogWatcher() {
@Override
public void onJsLog(int level, String log) {
MyLog.i(tag, log);
}
});
2023-07-04 21:48
x***@163.com

x***@163.com

安卓sdk开发有自定义属性吗? 具体实现方式有吗
2021-05-25 18:24
9***@qq.com

9***@qq.com

```
//run ui thread

@JSMethod(uiThread = true)

public void testAsyncFunc(JSONObject options, JSCallback callback) {

//在这里可不可以写Thread?比如:

new Thread(new Runnable(){

@Override

public void run(){

//code

callback.invoke(data);

}

}).start();

}
```
2021-05-08 14:35
9***@qq.com

9***@qq.com

//run ui thread
@JSMethod(uiThread = true)
public void testAsyncFunc(JSONObject options, JSCallback callback) {
//在这里可不可以写Thread?比如:
new Thread(new Runnable(){
@Override
public void run(){
//code
callback.invoke(data);
}
}).start();
}
2021-05-08 14:29
9***@qq.com

9***@qq.com


刚采完坑 https://liujingyuan.top/2020/06/12/Dcloud%E6%89%A9%E5%B1%95%E5%8E%9F%E7%94%9F%E7%BB%84%E4%BB%B6/
2020-06-12 18:56
DCloud_Android_ST

DCloud_Android_ST (作者)

回复 Json_One :
将参数放入到detail中
2020-03-27 19:42
Json_One

Json_One

为啥iOS的扩展写的那么详细。。。 fireEvent的params传过去接受不到怎么回事?
2020-03-26 18:15
DCloud_Android_ST

DCloud_Android_ST (作者)

回复 f***@163.com :
这是uni小程序原生扩展开发 与HBuilder X无关
2020-03-24 15:01
f***@163.com

f***@163.com

HBuilder X是不是和开发插件一样使用?要生成aar文件,配置package.json?
2020-03-18 10:33