一、混合app开发框架

    1:ionic
        Ionic 是一个强大的 HTML5 应用程序开发框架,可以帮助您使用 Web 技术,比如 HTML、CSS 和 Javascript 构建接近原生体验的移动应用程序。Ionic 主要关注外观和体验,以及和你的应用程序的 UI 交互,特别适合用于基于 Hybird 模式的 HTML5 移动应用程序开发。
    2:Flitter
        Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
    3:uni-app
        是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
    4:Taro
        Taro 是由京东 - 凹凸实验室打造的一套遵循 React 语法规范的多端统一开发框架。我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信小程序、H5、App 端等)运行的代码。

二、uniapp常用

    1:离线打包无权限
         我是进行的离线打包,需要把 manifest.json 的相关权限内容复制到离线项目的src/main/AndroidManifest.xml中复制xml内容到 manifest 节点下<uses-permission android:name="android.permission.CAMERA"/>
    2:安卓截屏

capture() {
    if (uni.getSystemInfoSync().platform != "android") {
        app.globalData.showToast("系统不支持下载");
        return;
    }
    var ws=this.$mp.page.$getAppWebview();
    var bitmap = new plus.nativeObj.Bitmap('cimg');
    uni.showLoading({
        title: "下载中..."
    });
    ws.draw(bitmap, function(){
        let rand = Math.floor(Math.random()*10000);
        let saveUrl = '_doc/'+rand+'cimg.jpg';
        bitmap.save(saveUrl, {}, function(i){
            uni.saveImageToPhotosAlbum({
                filePath: i.target,
                success: function () {
                    bitmap.clear();
                    setTimeout(()=>{
                        uni.hideLoading();
                        app.globalData.showToast("下载成功,请在手机相册中查找!");
                        },2000)
                },
            })
        }, function(e){
            console.log('下载失败:'+JSON.stringify(e));
        });
    }, function(e){
        console.log('下载保存图片失败:'+JSON.stringify(e));
    }, { check:true, // 设置为检测白屏
        clip:{top:'70',left:'0',height:'80%',width:'100%'} //设置截屏区域
    });
}

    3:安卓导出excel


if (uni.getSystemInfoSync().platform != "android") {
    app.globalData.showToast("系统不支持导出");
    return;
}
if (res.data.data.length <= 0) {
    app.globalData.showToast("没有数据可以导出");
    return;
}
//列标题
let worksheet = "sheet1";
let str = '<tr><td>xxx</td></tr>';
//循环遍历,每行加入tr标签,每个单元格加td标签
for (let i = 0; i < res.data.data.length; i++) {
    str += '<tr>';
    //增加\t为了不让表格显示科学计数法或者其他格式
    str += `<td>${ (res.data.data[i]['类别']?res.data.data[i]['xxx']:'') + '\t'}</td>`;
    str += '</tr>';
}
//下载的表格模板数据
let template = `<html xmlns:o="urn:schemas-microsoft-com:office:office" 
			    xmlns:x="urn:schemas-microsoft-com:office:excel" 
			    xmlns="http://www.w3.org/TR/REC-html40">
			    <head><!--[if gte mso 9]><xml encoding="UTF-8"><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
			    <x:Name>${worksheet}</x:Name>
			    <x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
			    </x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
			    </head><body><table>${str}</table></body></html>`;
//下载模板
exportFile(template);

// 导出文件到手机 fileData:要写入到文件的数据,返回参数为文档路径
function exportFile(fileData, documentName = "xxx") {
		/*
		PRIVATE_DOC: 应用私有文档目录常量
		PUBLIC_DOCUMENTS: 程序公用文档目录常量
		*/
		plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, function(fs) {

			let rootObj = fs.root;
			let fullPath = rootObj.fullPath;
			// let reader = rootObj.createReader();
			// console.log(reader);
			// reader.readEntries((res)=>{
			//     console.log(res); //这里拿到了该目录下所有直接文件和目录
			// },(err)=>{console.log(err);})

			console.log("开始导出数据...");
			// 创建文件夹
			rootObj.getDirectory(documentName, {
				create: true
			}, function(dirEntry) {
				//获取当前的年月继续创建文件夹
				let date = new Date();
				let year = date.getFullYear();
				let month = date.getMonth() + 1;
				dirEntry.getDirectory(`${year}年${month}月`, {
					create: true
				}, function(dirEntry2) {
					// 创建文件,防止重名
					let fileName = documentName+'-'+Date.now();
					dirEntry2.getFile(`${fileName}.xlsx`, {
						create: true
					}, function(fileEntry) {
						fileEntry.createWriter(function(writer) {
							writer.onwritestart = (e) => {
								uni.showLoading({
									title: "正在导出",
									mask: true
								})
							}
							//  /storage/emulated/0指的就是系统路径
							let pathStr = fullPath.replace("/storage/emulated/0", "");
							let docUrl = `${fullPath}${documentName}/${year}年${month}月/${fileName}.xlsx`
							docUrl = docUrl.replace("/storage/emulated/0", "");
							writer.onwrite = (e) => {
								// 成功导出数据;
								uni.hideLoading();
								setTimeout(() => {
									uni.showModal({
										title: "成功导出",
										showCancel: false,
										content: "文件路径:"+docUrl,
										success: (res) => {
										  if (res.confirm) {
												uni.openDocument({
													filePath: "file://storage/emulated/0"+docUrl,
													success: function(res) {
														console.log(docUrl)
													},
													fail: function(res) {
														console.log(res)
													}
												});
											}
										}
									})
								}, 500)
							};
							// 写入内容;
							writer.write(fileData);
						}, function(e) {
							console.log(e.message);
						});
					});
				})
			});
		});
	}

三、Android 签名

    1:使用java工具keytool生成签名证书
        keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore/.jks
    2:使用java工具keytool查看签名
        keytool -list -v -keystore test.keystore 或 keytool -printcert -jarfile test.apk。jdk1.8之后无法获取MD5签名信息
    3:使用Android Studio创建签名
        Build->Generate Signed Bundle / APK->NEXT后在Key store path处选择Create new填写信息后创建成功
    4:使用Android Studio查看签名
        

# 修改build.gradle文件
    signingConfigs {
        config {
            keyAlias 'xxx'
            keyPassword 'xxx'
            storeFile file('../xxx.jks')
            storePassword 'xxx'
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }
# 在gradle面板中运行Tasks中的signingReport,如果没有可以在运行中添加一个类型为gradle的Tasks的运行命令

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐