UNI-APP打包及原生交互教程

5,285 阅读7分钟

前言

在开发过程中学习的UNI-APP安卓端的配置及UNI-APP插件的简单制作,文中有一些知识需自行搜索,如有不对,请指出!

本文引用了 uniapp安卓原生插件开发流程-作者 AndroidLMY,如有侵权,请私信删除。

准备开发环境

  • 打开如下链接:Android Studio ,进入JDK1.8下载官网,或者直接百度JDK1.8,也可进入下载官网。

安卓配置

下载好App离线SDK后,接下来使用Android Studio打开官方下载的SDK包文件,HBuilder-HelloUniApp。使用import导入,不要使用open打开。

进入app->build.gradle文件中

配置镜像加速

修改配置,因网络问题,配置加速镜像。

如下:

    maven {
        url 'https://maven.aliyun.com/repository/google'
        name 'Google'
    }
    maven{url 'https://maven.aliyun.com/repository/public'}
    maven{url 'http://maven.aliyun.com/nexus/content/groups/public/'}
    maven{url 'https://maven.aliyun.com/repository/central'}
    maven { url 'https://maven.aliyun.com/repository/jcenter' }

然后点击右上角的

进行同步


修改包名以及程序名

如果需要配置自定义包名(不是修改安装好的软件名称)

请修改位置在app->build.gradle文件中

defaultConfig {
    applicationId "com.ceshidab.app"
    minSdkVersion 21
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
    ndk {
        abiFilters 'x86' , 'armeabi-v7a'
    }

    manifestPlaceholders = [
        "apk.applicationId" : "com.ceshidab.app" ,
        "GETUI_APPID" : "unipush的appid" ,
        "plus.unipush.appid" : "unipush的appid" ,
        "plus.unipush.appkey" : "unipuish的appkey" ,
        "plus.unipush.appsecret" : "unipush的secrety"
    ]
 }

修改完包名以后,记得同步修改app->src->main->java下的文件夹

com\ceshidab\app
文件夹层级对应包名

然后修改app->src->main->AndroidManifest.xml文件中的包名。

如果需要修改安装出来的软件名,在app->src->main->res->values->strings.xml

<resources>
    <string name="app_name">APP名称</string>
</resources>

配置证书步骤如下

使用Java生成一个签名密钥,此时,你应该已经安装好了JAVA以及安卓环境,

keytool -genkey -alias test -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore

Android平台签名证书(.keystore)生成指南 - DCloud问答,里面有详解。注意,生成密钥匙时的别名,密码等信息,后期在安卓打包的过程中会使用。


接下来配置安卓打包证书信息

位置在app->build.gradle文件中

signingConfigs {
    config {
        keyAlias 'test' // 证书别名
        keyPassword 'test' // 证书密码
        storeFile file( 'test.keystore' ) //该文件放在APP根目录下,与该配置文件同级
        storePassword 'test' // 证书密码
        v1SigningEnabled true
        v2SigningEnabled true
    }
}

UNI程序的打包及安卓第三方配置

生成本地打包资源

首先使用hbx编辑器生成安卓打包资源

然后去dev.dcloud.net.cn/申请开发者账号,并在编…

会在网站上同步生成一个新的APP,点击APP名称进入配置,然后点击左侧离线打包KEY管理,配置如下信息。


使用HBuilder X编辑器生成安卓打包资源,点击发行->原生APP本地打包->生成本地打包APP资源。等待程序执行完毕,会在unpackage->resources文件夹下生成打包好的资源。

将该文件夹复制进入安卓项目中,位置为 app->src->main->assets->apps。

注意是复制__UNI__888888文件夹。

然后修改两处安卓配置文件。

app->src->main->assets->data->dcloud_control.xml

<hbuilder>
    <apps>
        <app appid="__UNI__888888" appver=""/>
        /** appid 为在HBuilder X 中生成的appid */
    </apps>
</hbuilder>

app->src->main->assets->apps->__UNI__8888888->www->manifest.json

{ "@platforms" :[ "android" , "iPhone" , "iPad" ], "id" : "__UNI__8888888" , "name" : "test" , "version" :{ "name" : "1.0.0" , "code" : "100" }, "description" : "" , "launch_path" : "__uniappview.html" , "developer" :{ "name" : "" , "email" : "" , "url" : "" }, "permissions" :{ "UniNView" :{ "description" : "UniNView原生渲染" }}, "plus" :{ "useragent" :{ "value" : "uni-app" , "concatenate" :true}, "splashscreen" :{ "target" : "id:1" , "autoclose" :true, "waiting" :true, "delay" :0}, "popGesture" : "close" , "launchwebview" :{ "render" : "always" , "id" : "1" , "kernel" : "WKWebview" }, "statusbar" :{ "immersed" : "supportedDevice" , "style" : "dark" , "background" : "#F8F8F8" }, "usingComponents" :true, "nvueStyleCompiler" : "uni-app" , "compilerVersion" :3, "allowsInlineMediaPlayback" :true, "uni-app" :{ "compilerVersion" : "3.1.22" , "control" : "uni-v3" , "nvueCompiler" : "uni-app" , "renderer" : "auto" , "nvue" :{ "flex-direction" : "column" }, "nvueLaunchMode" : "normal" }, "launch_path" : "__uniappview.html" }}

该文件为打包的ID,一般无需修改。注意修改app->src->main->assets->data->dcloud_control.xml文件中的ID即可。

修改dcloud_appkey,位置app->src->main->AndroidManifest.xml,下面有叙述。

至此,一个有签名但是没有任何扩展配置的APP,就配置完毕了。


微信支付及登录配置

首先去微信的平台申请所需要的KEY值,包名填写你自己修改好的包名,然后输入微信所需要的证书值(上面生成的安卓证书),先打一个APP出来,安装到手机上。然后安装微信的签名获取工具,输入你的包名,会计算出一个值,复制到微信平台上即可。

然后在HBuilder X中勾选功能,并填写所需要的key。还有一个在安卓工程中填写配置的步骤,最后再说。

注:UNI的示例工程已集成好所需的扩展,无需重复添加。

安卓工程内的配置

修改app->src->main->AndroidManifest.xml文件,里面有各种配置信息,官方给的很详细。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="此处为你的包名">

... 官方文件内容
    <application
        android:name="io.dcloud.application.DCloudApplication"
        android:allowClearUserData="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:debuggable="true"
        >
       ... 官方文件内容
        <!-- Maps(地图) end -->
        <meta-data android:name="com.amap.api.v2.apikey"
            android:value="高德key"/>
        <service android:name="com.amap.api.location.APSService" />
        ... 官方文件内容
        <!-- 微信分享 配置begin -->
        <meta-data
            android:name="WX_SECRET"
            android:value="微信的secret" />
        <meta-data
            android:name="WX_APPID"
            android:value="微信的appid" />
        <activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="微信的appid" />
            </intent-filter>
        </activity>
        <!-- 微信分享 配置 end -->
        <!-- 微信支付配置 start -->
        <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop" />
        <meta-data
            android:name="WX_APPID"
            android:value="微信的appid" />
        <!-- 微信支付配置end -->
        ... 官方文件内容
        
       <!-- 此处为重点 dcloud_appkey -->
        <meta-data
            android:name="dcloud_appkey"
            android:value="开发者需登录https://dev.dcloud.net.cn/申请签名" />
    </application>
</manifest>
dcloud_appkey必须配置
dcloud_appkey 是APPID

里面的权限给的很多,根据个人需要酌情添加及删除。

奇怪的坑以及小技巧

canvasToTempFilePath报错

canvas绘制在IOS上可能会报错

{"errMsg":"canvasToTempFilePath:fail 不是DataURL数据,https://ask.dcloud.net.cn/article/282"}

此时检查一下是否使用了getImageInfo 做出以下处理即可

getImageInfo(img) {
    return new Promise((reslove, reject) => {
        // #ifdef APP-PLUS
        plus.io.getImageInfo({
            src: img,
            success: (res) => {
                reslove(res.path);
            },
            fail: (err) => {
                reject(err.errMsg);
            },
        });
        // #endif
        // #ifdef H5
        uni.getImageInfo({
            src: img,
            success: (res) => {
                reslove(res.path);
            },
            fail: (err) => {
                reject(err.errMsg);
            },
        });
        // #endif
    });
}

搜索 dc.fileprovider 即可

离线打包无法调用相机

修改AndroidManifest 文件

${你的包名}.dc.fileprovider

搜索 dc.fileprovider 即可

微信分享小程序

uni.share({
    provider: 'weixin',
    scene: "WXSceneSession", //固定值
    type: 5,
    imageUrl: 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/962fc340-4f2c-11eb-bdc1-8bd33eb6adaa.png',
    title: '欢迎体验uniapp',
    miniProgram: {
        id: 'gh_abcdefg',
        path: 'pages/index/index',
        type: 0,
        webUrl: 'http://uniapp.dcloud.io' // 这个必填,不填会报错
    },
    success: ret => {
        console.log(JSON.stringify(ret));
    }
});

全局弹窗

利用nvue进行弹窗的制作,新建nuve文件并在page.json中添加该页面。

{
      "path": "pages/popup/popup",
      "style": {
        "navigationStyle": "custom",
        "background": "transparent", //把页面背景设置透明,默认是白色
        "animationType": "fade-in",
        "enablePullDownRefresh": false
      }
},

每次需要弹窗的时候,保留当前页面并跳转即可。注:只在APP端生效。

uni.navigateTo({
    url: 'pages/popup/popup'
});

弹窗示例

<template>
  <view>
    <view class="mask" @click="goBack"></view>
    <view class="popup">
      <view class="shop-box" @touchmove.stop.prevent>
      
      </view>
    </view>
  </view>
</template>

<script>
// 使用vuex进行数据交互
import { mapGetters } from 'vuex';

export default {
  data() {
    return {};
  },
  computed: {
    ...mapGetters(['copyInfo']),
  },
  created() {},
  methods: {
    goBack() {
      uni.navigateBack({
        delta: 1
      });
    },
    goDetails(){
      uni.redirectTo({
          url: '/pages/a/a/?' + this.ObjectToParams({p:1})
      });
    },
    ObjectToParams(params) {
      let ParamsSrt = '?';
      Object.entries(params).forEach(([key, value]) => {
        ParamsSrt += `${key}=${value}&`;
      });
      ParamsSrt = ParamsSrt.substring(0, ParamsSrt.length - 1);
      return ParamsSrt;
    }
  }
};

</script>

<style scoped>
.popup {
  position: fixed;
  bottom: 0;
  right: 0;
  left: 0;
  top: 0;
  justify-content: center;
  align-items: center;
}

.mask {
  position: fixed;
  bottom: 0;
  right: 0;
  left: 0;
  top: 0;
  background: #000;
  opacity: 0.5;
}
</style>

NUVE注意点

nuve没有z-index,代码越靠后,层级越高。

UNI-APP插件的简单制作及理解

首先鸣谢大佬的文章给我的启发

地址 uniapp安卓原生插件开发流程-作者 AndroidLMY

可以直接去看这个文章!

个人理解

安卓文件创建

在安卓工程内新建一个Android Library的module 将app libs目录下的 uniapp-v8-release.aar包(名字可能不一样)复制到 toastplus libs下 然后修改新建的modle中的build.gradle文件 引入aar包

 /* 复制的UNI提供的项目的引入方式 */
repositories {
    flatDir {
     dirs 'libs'
    }
}
dependencies {
    implementation fileTree(include: [ '*.jar' ], dir: 'libs' )
    implementation fileTree(include: [ '*.aar' ], dir: 'libs' )
    implementation 'com.android.support:appcompat-v7:28.0.0'
    /*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所需库-----------------------结束*/
 }

点击右上角同步。 在modle目录下创建ToastPlus类继承UniMoudle。 注:如果你正确引入了arr文件,只需要跟随编辑器,让他自动引入即可。

下面贴一下大佬的代码

package com.example.toastplus; // 会自动创建 
import android.widget.Toast;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class ToastPlus extends UniModule {

    JSCallback jsCallback;
    String path = "" ;
/**
* 简单回调示例
* 传入一个String类型 处理并返回
*/

 @JSMethod(uiThread = true)
    public void processData(String data, JSCallback jsCallback) {
        this.jsCallback = jsCallback;
        if (mWXSDKInstance != null && mWXSDKInstance.getContext() != null) {
            path = data + "+(处理完成)" ;
            //返回处理结果 进行回调
            jsCallback.invoke(path);
        }
    }

/**
* 调用原生Toast显示传入内容
*/
 @JSMethod(uiThread = true)
    public void showToast(String message) {
        if (mWXSDKInstance != null && mWXSDKInstance.getContext() != null) {
            Toast.makeText(mWXSDKInstance.getContext(), message, Toast.LENGTH_SHORT).show();
        }
    }  
}

然后在app->dcloud_uniplugins.json文件中添加插件信息,没有就新建一个

{

  "nativePlugins" : [
    {
      "plugins" : [
        {
          "type" : "module" , // 不用改
          "name" : " toastplus " , // 你新建的module的名称
          "class" : " com.example.test . ToastPlus " // 完整的类名 包名+类名
        }
      ]
    }
  ]
}

创建UNI项目

此处依旧复制大佬的代码并增加一些小理解

<template>
  <view class="content">
    <view class="button1">
      <button @click="showToast(message)">点击显示原生Toast</button>
    </view>
    <view class="button2">
      <button @click="processData(waitprocessdata)">回调的使用</button>
    </view>
  </view>
</template>

<script>
//uni.requireNativePlugin("你新建的module的名称"); 参照 app->dcloud_uniplugins.json的配置
const ToastPlusModule = uni.requireNativePlugin("toastplus");

export default {
  data() {
    return {
      message: "我是一条很长的Toast我是一条很长的Toast",
      waitprocessdata: "我是待处理的数据",
    };
  },
  onLoad() {},
  methods: {
    showToast(message) {
      ToastPlusModule.showToast(message);
    },
    processData(data) {
      ToastPlusModule.processData(data, (processokdata) => {
        ToastPlusModule.showToast(processokdata);
      });
    },
  },
};

</script>

<style>
...
自行编写
</style>

调试插件

在app->build.gradle中引入新建的module。

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    implementation fileTree(include: [ '*.jar' ], dir: 'libs' )
    implementation fileTree(include: [ '*.aar' ], dir: 'libs' )
    implementation 'com.android.support:appcompat-v7:28.0.0'
    /*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'
    
    // 此处是你新添加的module
    implementation project( ": toastplus " )
 }

然后将你创建的项目打包即可。参照上面的生成本地打包资源即可。