您现在的位置是:网站首页> 小程序设计

uniapp原生调用技术收集

摘要

uniapp原生调用技术收集

dcloud的原生代码例子

1.png


Native.js入门指南

Native API经典实用例子

uniapp如何使用Android的库aar

uniapp插件编写

uniapp的uts可以调用第三方aar jar



uniapp如何使用Android的库aar

以下是 uni-app 使用 Android 的库 aar 的步骤:

创建 Android 原生插件

打开 Android Studio,新建一个项目,选择 “No Activity”。

右键点击项目,选择 “New > Module”,然后选择 “Android Library”,命名为例如 “MyUniPlugin”。

在创建的模块中编写插件代码,编写一个类继承自 io.dcloud.feature.uniapp.common.UniModule,并使用 @UniJSMethod 注解标注需要暴露给 uni-app 的方法。例如:

无返回值方法:

java


@UniJSMethod

public void showToast(String message) {

    Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();

}

* 有返回值方法:

java


@UniJSMethod

public String syncMethod(String param) {

    return "Received: " + param;

}

* 带回调方法:

java


@UniJSMethod

public void asyncMethod(JSONObject params, UniJSCallback callback) {

    try {

        String message = params.getString("message");

        callback.invoke(new JSONObject().put("result", "Echo: " + message));

    } catch (Exception e) {

        callback.invoke(new JSONObject().put("error", e.getMessage()));

    }

}

在模块的 build.gradle 文件中添加 Uni-app 的依赖,如 implementation 'com.github.aliyun-alpha:uni-app:8.0.0'。

点击右侧 “Gradle” 窗口中的 :mylibrary → Tasks → build → assemble,生成 aar 文件,位于 mylibrary/build/outputs/aar/mylibrary-release.aar。

配置 uni-app 项目

在 uni-app 项目的根目录下创建 nativeplugins 文件夹,在该文件夹下创建与 aar 插件同名的文件夹,例如 “MyUniPlugin”,在该文件夹下再创建 “android” 文件夹,将 aar 文件放入其中,如有第三方库还需创建 libs 文件夹并放入对应的 jar 包。

在 “MyUniPlugin” 文件夹下创建 package.json 文件,内容如下:

JSON

复制

{

  "name": "MyUniPlugin",

  "id": "com.example.myuniplugin",

  "version": "1.0.0",

  "description": "Custom AAR Plugin",

  "_dp_type": "nativeplugin",

  "_dp_nativeplugin": {

    "android": {

      "plugins": [

        {

          "type": "module",

          "name": "com.example.myuniplugin",

          "class": "com.example.myuniplugin.MyUniPlugin"

        }

      ],

      "integrateType": "aar",

      "minSdkVersion": 21

    }

  }

}

在 uni-app 项目的 manifest.json 文件中勾选原生插件,选择本地插件并找到 “MyUniPlugin”。

调用 Android aar 中的方法

在 uni-app 页面的 JavaScript 代码中,使用 uni.requireNativePlugin() 方法引入插件,然后调用插件中定义的方法,例如:

JavaScript


<template>

  <view>

    <button @click="callToast">显示 Toast</button>

    <button @click="callSync">调用同步方法</button>

    <button @click="callAsync">调用异步方法</button>

  </view>

</template>


<script>

export default {

  methods: {

    callToast() {

      const myPlugin = uni.requireNativePlugin('MyUniPlugin');

      myPlugin.showToast('Hello from uni-app');

    },

    callSync() {

      const myPlugin = uni.requireNativePlugin('MyUniPlugin');

      const result = myPlugin.syncMethod('Hello Sync');

      console.log('同步结果:', result);

    },

    callAsync() {

      const myPlugin = uni.requireNativePlugin('MyUniPlugin');

      myPlugin.asyncMethod(

        { message: 'Hello Async' },

        (res) => {

          if (res.error) {

            console.error('异步错误:', res.error);

          } else {

            console.log('异步结果:', res.result);

          }

        }

      );

    }

  }

}

</script>

打包运行

运行到 Android 设备:在 HBuilderX 中选择 “运行 → 运行到手机或模拟器”,将应用运行到 Android 设备上进行测试。



uniapp插件编写

点击查看官方文档

一个原生插件例子

uts插件和Native.js的区别



一个原生插件例子:

DCloud-RichAlert 插件

DCloud-RichAlert插件源码点击下载

RichAlertModule.java源码

RichAlert.java源码

插件介绍 :这是一个富文本弹窗插件,可在弹窗中显示富文本内容。

获取方式 :可从 uni 原生插件市场 下载免费的 DCloud-RichAlert 插件,下载后得到 zip 格式的文件,将其解压到 HBuilderX 的 uni-app 项目下的 “nativeplugins” 目录。

配置方法 :在 manifest.json 的 “App 原生插件配置” 中,选择本地插件,找到并选择 DCloud-RichAlert 插件,保存后提交云端打包生效。

调用示例 :

JavaScript

const dcRichAlert = uni.requireNativePlugin('DCloud-RichAlert');

dcRichAlert.show({

    title: "测试标题",

    message: "这是一条富文本消息",

    buttonText: "确定",

    success: (res) => {

        console.log("弹窗关闭", res);

    }

});


这个插件压缩包解压后目录结构

1.png


1.png

package.json内容

{

"name": "RichAlert",

"id": "DCloud-RichAlert",

"version": "0.1.3",

"description": "示例插件",

"_dp_type":"nativeplugin",

"_dp_nativeplugin":{

"ios": {

"plugins": [

{

"type": "module",

"name": "DCloud-RichAlert",

"class": "DCRichAlertModule"

}

],

"integrateType": "library",

"deploymentTarget": "8.0"

},

"android": {

"plugins": [

{

"type": "module",

"name": "DCloud-RichAlert",

"class": "uni.dcloud.io.uniplugin_richalert.RichAlertWXModule"

}

],

"integrateType": "aar",

"minSdkVersion" : 16

}

}

}

工程主要截取:

app下build.gradle重要添加

/*uniapp所需库-----------------------开始*/

    implementation 'com.android.support:recyclerview-v7:28.0.0'

    implementation 'com.facebook.fresco:fresco:1.13.0'

    implementation "com.facebook.fresco:animated-gif:1.13.0"

    /*uniapp所需库-----------------------结束*/

    // 基座需要,必须添加

    implementation 'com.github.bumptech.glide:glide:4.9.0'

    implementation 'com.alibaba:fastjson:1.1.46.android'

    // 添加uni-app插件

    implementation project(':uniplugin_richalert')


uniplugin_richalert下的build.gradle重要添加

implementation fileTree(dir: 'libs', include: ['*.jar'])

compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])


RichAlertModule.java源码

package uni.dcloud.io.uniplugin_richalert;


import android.app.Activity;

import android.content.DialogInterface;

import android.graphics.Color;

import android.text.TextUtils;


import com.alibaba.fastjson.JSONArray;

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.UniDestroyableModule;

import io.dcloud.feature.uniapp.utils.UniLogUtils;

import io.dcloud.feature.uniapp.utils.UniResourceUtils;


public class RichAlertModule extends UniDestroyableModule {

    public String CONTENT = "content";

    public String CONTENT_COLOR  = "contentColor";

    public String CONTENT_ALIGN  = "contentAlign";

    public String POSITION = "position";

    public String BUTTONS = "buttons";

    public String CHECKBOX = "checkBox";

    public String TITLE_ALIGN = "titleAlign";

    //默认黑色

    public static int defColor = Color.BLACK;


    RichAlert alert;


    @UniJSMethod(uiThread = true)

    public void show(JSONObject options, UniJSCallback jsCallback) {

        if (mWXSDKInstance.getContext() instanceof Activity) {

            String content = options.getString(CONTENT);

            int contentColor = UniResourceUtils.getColor(options.getString(CONTENT_COLOR), defColor);

            String contentAlign = options.getString(CONTENT_ALIGN);


            String title = options.getString(RichAlert.TITLE);

            int titleColor = UniResourceUtils.getColor(options.getString(RichAlert.TITLE_COLOR), defColor);

            String titleAlign = options.getString(TITLE_ALIGN);


            String postion = options.getString(POSITION);


            RichAlert richAlert = new RichAlert(mWXSDKInstance.getContext());


            JSONArray buttons = options.getJSONArray(BUTTONS);

            JSONObject checkBox = options.getJSONObject(CHECKBOX);


            if(!TextUtils.isEmpty(title)) {

                richAlert.setTitle(title, titleColor, titleAlign);

            }

            if(!TextUtils.isEmpty(content)) {

                richAlert.setContent(content, contentColor, contentAlign,jsCallback);

            }

            if(checkBox != null) {

                richAlert.setCheckBox(checkBox, jsCallback);

            }

            if(buttons != null) {

                richAlert.setButtons(buttons, jsCallback);

            }

            if(!TextUtils.isEmpty(postion)) {

                richAlert.setPosition(postion);

            }


            richAlert.show();

            tracking(richAlert, jsCallback);

        }

    }


    private void tracking(RichAlert dialog, final UniJSCallback jsCallback) {

        alert = dialog;

        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override

            public void onCancel(DialogInterface dialog) {

                JSONObject result = new JSONObject();

                result.put("type", "backCancel");

                jsCallback.invoke(result);

            }

        });

        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

            @Override

            public void onDismiss(DialogInterface dialog) {

                alert = null;

            }

        });

    }


    @UniJSMethod(uiThread = true)

    public void dismiss() {

        destroy();

    }


    @Override

    public void destroy() {

        if (alert != null && alert.isShowing()) {

            UniLogUtils.w("Dismiss the active dialog");

            alert.dismiss();

        }

    }


}


RichAlert.java源码:

package uni.dcloud.io.uniplugin_richalert;


import android.app.AlertDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.graphics.Color;

import android.support.annotation.NonNull;

import android.text.SpannableStringBuilder;

import android.text.Spanned;

import android.text.TextUtils;

import android.text.method.LinkMovementMethod;

import android.text.style.ClickableSpan;

import android.text.style.ForegroundColorSpan;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.View;

import android.view.ViewGroup;

import android.view.Window;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.CompoundButton;

import android.widget.LinearLayout;

import android.widget.ScrollView;

import android.widget.TextView;


import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;


import java.io.ByteArrayInputStream;

import java.io.InputStream;

import java.util.ArrayList;


import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;


import io.dcloud.feature.uniapp.bridge.UniJSCallback;

import io.dcloud.feature.uniapp.utils.UniResourceUtils;

import uni.dcloud.io.uniplugin_richalert.Info.Person;

import uni.dcloud.io.uniplugin_richalert.Info.SaxHelper;



public class RichAlert {


    public static String TITLE = "title";

    public static String TITLE_COLOR = "titleColor";


    int mPositiveColor = Color.BLACK;

    int mNegativeColor = Color.BLACK;

    int mNeutralColor = Color.BLACK;

    int mPosition = Gravity.CENTER;

    Context mContext;

    LinearLayout mContentViewRootView;

    CheckBox mCheckBox;

    TextView mMessageView;

    TextView mTitleView;

    AlertDialog mAlertDialog;

    AlertDialog.Builder mBuilder;


    String SELECTED = "isSelected";


    public RichAlert(@NonNull Context context) {

        mContext = context;

        mBuilder = new AlertDialog.Builder(context);

    }


    /**

     * 显示弹窗

     */

    public void show() {

        mAlertDialog = mBuilder.create();

        if(mContentViewRootView != null) {

            mAlertDialog.setView(mContentViewRootView);

            if(mCheckBox != null) {

                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

                layoutParams.leftMargin = dip2px(mContext, 11);

                mContentViewRootView.addView(mCheckBox, layoutParams);

            }

        }


        mAlertDialog.setCanceledOnTouchOutside(false);

        mAlertDialog.show();


        setButtonColor(AlertDialog.BUTTON_POSITIVE, mPositiveColor);

        setButtonColor(AlertDialog.BUTTON_NEGATIVE, mNegativeColor);

        setButtonColor(AlertDialog.BUTTON_NEUTRAL, mNeutralColor);


        Window dialogWindow = mAlertDialog.getWindow();//获取window对象

        dialogWindow.setGravity(mPosition);

    }


    /**

     * 设置弹窗标题

     * @param title

     * @param Color

     * @return

     */

    public RichAlert setTitle(CharSequence title, int Color, String align) {

//        mBuilder.setTitle(title);

        initContentView(mContext);

        if(mTitleView != null) {

            mTitleView.setVisibility(View.VISIBLE);

            mTitleView.setText(title);

            mTitleView.setTextColor(Color);

            mTitleView.setGravity(getAlign(align) | Gravity.CENTER_VERTICAL);

        }

        return this;

    }


    /**

     * 设置弹窗主显示内容

     * @param content

     * @param Color

     * @param jsCallback

     * @return

     */

    public RichAlert setContent(String content, int Color, String align, UniJSCallback jsCallback) {

        try {

            initContentView(mContext);

            ArrayList<Person> data = readxmlForDom(content);

            if(data != null && data.size() > 0) {

                CharSequence ct = getContentCharSequence(data, jsCallback);

                mMessageView.setText(ct);

            } else {

                mMessageView.setText(content);

            }

            mMessageView.setTextColor(Color);

            mMessageView.setGravity(getAlign(align));


        } catch (Exception e) {

            e.printStackTrace();

        }

        return this;

    }



    /**

     * 生成自定义内容布局

     * 此处使用代码编写的布局,也可以使用XML布局方式加载

     * @param context

     */

    private void initContentView(Context context) {

        if(mContentViewRootView == null && context != null) {

            mContentViewRootView = new LinearLayout(context);

            mContentViewRootView.setOrientation(LinearLayout.VERTICAL);

            LinearLayout titleLayout = new LinearLayout(context);

            mTitleView = new TextView(context);

            mTitleView.setGravity(Gravity.CENTER);

            mTitleView.setPadding(dip2px(mContext, 16), 0, dip2px(mContext, 16), 0);

            mTitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);

            LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(mContext, 45));

            titleLayout.addView(mTitleView, titleParams);

            mTitleView.setVisibility(View.GONE);

            mContentViewRootView.addView(titleLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

            ScrollView scrollView = new ScrollView(context);

            mMessageView = new TextView(context);

            ScrollView.LayoutParams params = new ScrollView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

            params.topMargin = dip2px(context, 25);

            params.bottomMargin = dip2px(context, 25);

            params.leftMargin = dip2px(context, 16);

            params.rightMargin = dip2px(context, 16);

            mContentViewRootView.addView(scrollView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1));

            scrollView.addView(mMessageView, params);

            mMessageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);

            mMessageView.setMovementMethod(LinkMovementMethod.getInstance());

        }

    }


    /**

     * 设置弹窗按钮

     * @param buttons

     * @param jsCallback

     * @return

     */

    public RichAlert setButtons(JSONArray buttons, final UniJSCallback jsCallback) {

        if(buttons != null && buttons.size() > 0) {

            for(int i = 0; i < buttons.size();i++) {

                JSONObject button = buttons.getJSONObject(i);

                String title = button.getString(TITLE);

                int color = UniResourceUtils.getColor(button.getString(TITLE_COLOR), RichAlertModule.defColor);

                if(TextUtils.isEmpty(title)) {

                    continue;

                }

                if(i > 2) { //buttons 最多支持三个button

                    return this;

                }

                final int index = i;

                DialogInterface.OnClickListener listener =  new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialogInterface, int n) {

                        JSONObject result = new JSONObject();

                        result.put("type", "button");

                        result.put("index", index);

                        jsCallback.invoke(result);

                    }

                };

                switch(i) {

                    case 0: {

                        mBuilder.setNegativeButton(title, listener);

                        mNegativeColor = color;

                        break;

                    }

                    case 1: {

                        mBuilder.setNeutralButton(title, listener);

                        mNeutralColor = color;

                        break;

                    }

                    case 2: {

                        mBuilder.setPositiveButton(title, listener);

                        mPositiveColor = color;

                        break;

                    }

                }

            }

        }

        return this;

    }



    /**

     * 设置按钮文字颜色

     * 需要在show操作之后调用

     * @param type

     * @param color

     */

    private void setButtonColor(int type, int color) {

        if(mAlertDialog != null) {

            Button button = mAlertDialog.getButton(type);

            if(button != null) {

                button.setTextColor(color);

            }

        }

    }


    /**

     * 提示框位置

     * @param position

     * @return

     */

    public RichAlert setPosition(String position) {

        mPosition = getAlign(position);

        return this;

    }


    /**

     * 设置复选框提示

     * @param checkBox

     * @param jsCallback

     * @return

     */

    public RichAlert setCheckBox(JSONObject checkBox, final UniJSCallback jsCallback) {

        if(checkBox == null) {

            return this;

        }

        mCheckBox = new CheckBox(mContext);


        mCheckBox.setText(checkBox.getString(TITLE));

        int color = UniResourceUtils.getColor(checkBox.getString(TITLE_COLOR), RichAlertModule.defColor);

        mCheckBox.setTextColor(color);

        boolean isSelected = false;

        if(checkBox.containsKey(SELECTED)) {

            isSelected = checkBox.getBoolean(SELECTED);

        }

        mCheckBox.setChecked(isSelected);

        mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override

            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                JSONObject result = new JSONObject();

                result.put("type", "checkBox");

                result.put("isSelected", isChecked);

                jsCallback.invokeAndKeepAlive(result);

            }

        });

        return this;

    }



    /**

     * 将Person转换对应的Span

     * @param data

     * @param jsCallback

     * @return

     */

    private CharSequence getContentCharSequence(ArrayList<Person> data, UniJSCallback jsCallback) {

        SpannableStringBuilder spannableString = new SpannableStringBuilder();

        for(Person person : data) {

            if(TextUtils.isEmpty(person.content)) {

                continue;

            }

            if(person.label.equalsIgnoreCase("a")) {

                setASpan(spannableString, person, jsCallback);

            } else {

                spannableString.append(person.content);

            }

        }


        return spannableString;

    }


    /**

     * 设置A标签指定的Span 包含点击事件

     * @param spannableString

     * @param person

     * @param jsCallback

     */

    private void setASpan(SpannableStringBuilder spannableString, final Person person, final UniJSCallback jsCallback) {

        int start = spannableString.toString().length();

        spannableString.append(person.content);

        int end = spannableString.toString().length();

        ClickableSpan clickableSpan = new ClickableSpan() {


            public void onClick(View view) {

                //Do something with URL here.

                JSONObject result = new JSONObject();

                result.put("type", "a");

                result.putAll(person.attribute);

                jsCallback.invokeAndKeepAlive(result);

            }

        };

        spannableString.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        ForegroundColorSpan foregroundColorSpan=new ForegroundColorSpan(Color.BLUE);

        spannableString.setSpan(foregroundColorSpan,start,end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

    }


    /**

     * 解析XML 获取person数组

     * @param content

     * @return

     * @throws Exception

     */

    private ArrayList<Person> readxmlForDom(String content) throws Exception {

        content = "<RichP>" + content + "</RichP>";

        //获取文件资源建立输入流对象

        InputStream is = new ByteArrayInputStream(content.getBytes());

        //创建一个SAXParserFactory解析器工程

        SAXParserFactory factory = SAXParserFactory.newInstance();

        SaxHelper helper = new SaxHelper();

        //③创建SAX解析器

        SAXParser parser = factory.newSAXParser();

        parser.parse(is, helper);

        return helper.getPersons();

    }


    public boolean isShowing() {

        return mAlertDialog == null ? false : mAlertDialog.isShowing();

    }


    public void dismiss() {

        if(mAlertDialog != null) {

            mAlertDialog.dismiss();

            mAlertDialog = null;

            mContentViewRootView.removeAllViews();

            mContentViewRootView = null;

            mMessageView = null;

            mTitleView = null;

            mCheckBox = null;

        }

    }


    public void setOnDismissListener(DialogInterface.OnDismissListener listener) {

        if(mAlertDialog != null)

            mAlertDialog.setOnDismissListener(listener);

    }


    public void setOnCancelListener(DialogInterface.OnCancelListener listener) {

        if(mAlertDialog != null)

            mAlertDialog.setOnCancelListener(listener);

    }


    private int dip2px(Context context, float dipValue) {

        float scale =  context.getResources().getDisplayMetrics().density;

        return (int) (dipValue * scale + 0.5f);

    }


    private int getAlign(String alignString) {

        int align = Gravity.CENTER;

        if(!TextUtils.isEmpty(alignString)) {

            switch (alignString) {

                case "left":

                    align = Gravity.LEFT;

                    break;

                case "right" :

                    align = Gravity.RIGHT;

                    break;

                case "bottom":

                    align = Gravity.BOTTOM;

                    break;

            }

        }

        return align;

    }

}



uts插件和Native.js的区别

Native.js 运行在js上,通过反射调用os api。功能和性能都不及原生

uts 在 app 上不运行在 js 引擎里,是真正的原生。

点击查看实例代码

hello-uts例程

uts for android文档

uts语法介绍

uts平台专有对象和API 

创建uts插件

注意: 目前仅支持通过HBuilder X 创建和使用UTS插件,不支持通过cli的方式使用UTS插件

HBuilderX项目中uts插件目录结构

在 uni-app / uni-app x 的项目工程下,提供了独立的目录 utssdk,来存放 uts 插件。

当然官方更推荐使用 uni_modules 方式,这是更好的包管理方案。

首先确保项目根目录存在 uni_modules 文件夹,如果不存在,需要手动创建一个。

1.jpg


新建步骤拆解

右键点击uni_modules目录 -> 新建插件


1.jpg


选择类型 uts插件


2.jpg


为了避免和插件市场的其他插件冲突,建议起一个自己的插件前缀名称。


uts插件目录结构


3.jpg


package.json

package.json 为 uni_modules 插件配置清单文件,负责描述插件的基本配置。


{

  "id": "uts-helloworld",

  "displayName": "uts插件示例",

  "version": "0.1",

  "description": "uts插件示例",

  "uni_modules": {


  }

}

上面是一个默认的清单文件示例,关于 package.json 更多描述详见

插件的目录结构

1.png

根目录 index.uts 文件是程序主入口。如果插件根目录下没有 index.uts,则会在编译到不同平台时,寻找分平台的目录下的 index.uts 文件。

比如编译到 app-android 平台时,如果 uts 插件根目录没有 index.uts,会寻找 utssdk/app-android/index.uts。如果也没有找到,会报错。

当同时存在分平台目录的 index.uts 和根目录 index.uts 时,会优先获取具体的分平台目录。

开发者有多种组织自己代码的方式:

在插件根目录的 index.uts 中写条件编译代码。简单的业务一个文件搞定

在插件根目录 index.uts 中写条件编译,import 分平台的文件

不写根目录的 index.uts,直接在分平台目录写 index.uts。不跨端时,比如只做一个 Android 插件,这样写比较简单

插件对外暴露能力的总入口在 interface.uts ,他与 index.uts的关系是声明和实现的关系。


Android平台原生配置

app-android 文件夹下存在Android平台原生配置,包括以下目录或文件

目录名/文件名 用途

assets Android平台原生assets资源目录

libs Android平台原生引用的三方jar/aar目录

res Android平台原生res资源目录

AndroidManifest.xml Android平台原生应用清单文件

config.json Android平台下的配置文件

index.uts 主入口,interface.uts/index.d.ts声明的能力在Android平台下的实现


libs

Android平台原生三方库目录,支持以下类型文件:

jar

aar

so库

注意:UTS插件本地调试不支持直接使用so文件,需要将so文件和调用代码封装为AAR 或者分别集成 so和jar文件



uniapp的uts可以调用第三方aar jar

uts for android文档

hello-uts例程

uts语法介绍

uts平台专有对象和API

在 uni-app 的 UTS(Unified TypeScript)中是可以调用第三方 AAR 和 JAR 文件的。以下是具体介绍:

调用方式

将文件放在 libs 目录 :将第三方的 AAR 或 JAR 文件直接复制到 utssdk/app-android/libs 目录下即可使用。不过需要注意的是,如果使用的是标准基座进行调试,通常只能获取到 AAR 文件中的公开常量,如果要获取相关类的话,可能会报错提示找不到类。

通过远程依赖配置 :对于远程的插件,可以通过配置 config.json 来添加依赖。

注意事项

依赖冲突问题 :多个 UTS 插件引用相同第三方原生 SDK 时可能会产生冲突,所以如果 SDK 支持仓储,建议优先使用仓储配置,而不是直接把 JAR 等文件放在 libs 目录。

自定义基座问题 :如果需要获取 AAR 包中的类,可能需要先进行 app 运行制作自定义基座。

so 文件处理 :对于包含 so 库的第三方 SDK,保存到 libs 目录时需要按照 Android abi 类型分别存放。在 HBuilderX 4.26 版本之前,UTS 插件本地调试尚不支持直接使用 so 文件,需要将 so 文件和调用代码封装为 AAR 或者分别集成 so 和 jar 文件。

示例代码

java

// 在 UTS 中导入并使用第三方库中的类

import com.example.thirdlib.ThirdClass;

let thirdObj = new ThirdClass();

thirdObj.doSomething();


UTSAndroid

一个 UTSAndroid 的使用示例,展示如何在 uni-app 的 UTS 插件中调用 Android 原生 API:

获取应用上下文

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';


const context = UTSAndroid.getAppContext();

console.log("App Context:", context);

调用原生 Toast

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';

import Toast from 'android.widget.Toast';


export function showToast(message: string): void {

    UTSAndroid.getUniActivity()!.runOnUiThread(() => {

        Toast.makeText(UTSAndroid.getUniActivity(), message, Toast.LENGTH_LONG).show();

    });

}

在页面中调用:

TypeScript

复制

showToast("Hello from UTSAndroid!");

启动新的 Activity

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';

import Intent from 'android.content.Intent';


export function startNewActivity(): void {

    const intent = new Intent(UTSAndroid.getUniActivity(), YourActivityClass.javaClass);

    UTSAndroid.getUniActivity()!.startActivity(intent);

}

在页面中调用:

TypeScript

复制

startNewActivity();

监听 Activity 结果

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';

import Intent from 'android.content.Intent';


export function takePicture(): void {

    const takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    UTSAndroid.getUniActivity()!.startActivityForResult(takePictureIntent, 999);

    UTSAndroid.onAppActivityResult((requestCode: number, resultCode: number, data?: Intent) => {

        if (requestCode === 999) {

            console.log("Capture result received");

            // Handle the captured image here

        }

    });

}

在页面中调用:

TypeScript

复制

takePicture();

使用原生资源

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';

import R from 'com.uts.demo.R';


export function useNativeResource(): void {

    const stringResource = UTSAndroid.getAppContext().getResources().getString(R.string.hello_world);

    console.log("Native string resource:", stringResource);

}

在页面中调用:

TypeScript

复制

useNativeResource();

以上示例展示了如何在 UTS 插件中使用 UTSAndroid 来调用 Android 原生 API,包括获取应用上下文、显示 Toast、启动新 Activity、监听 Activity 结果以及使用原生资源等




UTSAndroidHookProxy

一个关于 UTSAndroidHookProxy 的使用示例:

定义接口实现类

在 UTS 插件代码中,创建一个类并实现 UTSAndroidHookProxy 接口。例如,创建一个 MyUTSAndroidHookProxy 类,用于在应用启动时初始化三方 SDK。

TypeScript

复制

import { UTSAndroidHookProxy } from '@dcloudio/uts-uniapp-android';


export class MyUTSAndroidHookProxy implements UTSAndroidHookProxy {

    onCreate(application: any): void {

        // 在这里进行三方 SDK 初始化等操作

        console.log("UTSAndroidHookProxy onCreate called");

        // 初始化三方 SDK 的代码示例

        // ThirdPartySDK.initialize(application);

    }

}

在页面中调用初始化操作

在页面中引入并实例化 MyUTSAndroidHookProxy 类,并调用相关方法完成初始化工作。

TypeScript

复制

import { MyUTSAndroidHookProxy } from '@/path/to/MyUTSAndroidHookProxy';


const myHookProxy = new MyUTSAndroidHookProxy();

myHookProxy.onCreate(this);

注意事项

由于 UTSAndroidHookProxy 初始化要早于 uni,所以不支持调用 uni API。如果需要调用 uni API,需要在初始化完成后进行。

一个插件只允许实现一个 UTSAndroidHookProxy 接口类。

onCreate 回调后应尽可能的判断隐私合规是否同意再初始化,否则可能会影响 app 上架。

Android 平台添加或修改 UTSAndroidHookProxy 实现代码需要重新提交云端打包才能生效。

完整示例代码

在 UTS 插件中创建一个文件(如 my-hook-proxy.ts),定义 MyUTSAndroidHookProxy 类:

TypeScript

复制

import { UTSAndroidHookProxy } from '@dcloudio/uts-uniapp-android';


export class MyUTSAndroidHookProxy implements UTSAndroidHookProxy {

    onCreate(application: any): void {

        console.log("UTSAndroidHookProxy onCreate called");

        // 初始化三方 SDK 的代码示例

    }

}

 * 在页面中引入并使用该类:

TypeScript

复制

import { MyUTSAndroidHookProxy } from '@/path/to/my-hook-proxy';


const myHookProxy = new MyUTSAndroidHookProxy();

myHookProxy.onCreate(this);

 * 如果需要在应用启动时自动初始化,可以将上述代码放在应用入口文件中。

示例说明 :通过实现 UTSAndroidHookProxy 接口,开发者可以在应用的 onCreate 阶段调用相应的逻辑,如初始化三方 SDK。这在需要在应用启动时进行特定初始化操作的场景中非常有用,例如集成推送 SDK、广告 SDK 等。需要注意的是,使用此接口时要遵循相关规范和注意事项,以确保应用的正常运行和上架合规性


UTSActivityCallback


一个 UTSActivityCallback 的使用示例,用于监听 Android 原生 Activity 的生命周期事件:

创建回调类

在 UTS 插件中创建一个类,实现 UTSActivityCallback 接口,覆盖所需的生命周期方法:

TypeScript

复制

import { UTSActivityCallback } from '@dcloudio/uts-uniapp-android';


export class MyActivityCallback implements UTSActivityCallback {

    onActivityCreated(activity: any, savedInstanceState: any): void {

        console.log('Activity created:', activity);

    }


    onActivityStarted(activity: any): void {

        console.log('Activity started:', activity);

    }


    onActivityResumed(activity: any): void {

        console.log('Activity resumed:', activity);

    }


    onActivityPaused(activity: any): void {

        console.log('Activity paused:', activity);

    }


    onActivityStopped(activity: any): void {

        console.log('Activity stopped:', activity);

    }


    onActivitySaveInstanceState(activity: any, outState: any): void {

        console.log('Activity save instance state:', activity);

    }


    onActivityDestroyed(activity: any): void {

        console.log('Activity destroyed:', activity);

    }

}

注册回调

在页面或插件的适当位置,注册 MyActivityCallback:

TypeScript

复制

import { UTSAndroid } from '@dcloudio/uts-uniapp-android';

import { MyActivityCallback } from './path/to/MyActivityCallback';


const myCallback = new MyActivityCallback();

UTSAndroid.onActivityCallback(myCallback); // 注册回调

反注册回调

在不需要监听时,及时反注册回调,避免内存泄漏:

TypeScript

复制

UTSAndroid.offActivityCallback(myCallback); // 反注册回调

注意事项

确保在调用 onActivityCallback 和 offActivityCallback 方法时,传入的回调对象是同一个实例。

UTSActivityCallback 的兼容性要求 uni-app x 版本和 Android UTS 插件版本均在 4.18 及以上。

如果是在页面中使用,建议在页面的生命周期函数(如 onLoad 或 onReady)中注册回调,并在页面的 onUnload 中反注册回调,以确保回调的正确注册和反注册。

通过上述代码,可以监听 Activity 的生命周期事件,并在对应的回调方法中执行相应的逻辑







上一篇:uniapp实战总结

Top