admin 管理员组文章数量: 887629
开发至简网格的过程中,既要做服务侧开发,也要多端开发,服务侧分为JAVA服务侧、Android服务侧,端侧分为安卓、Windows,技术繁杂,碰到不少基本问题,全部记录在这里,便于以后查找。
顺便做个小广告,至简网格是一套端&云结合的开发框架,极大简化了服务侧与端侧开发,服务侧使用简单的json配置与sql、js脚本,就可以搞定95%以上的业务场景;端侧支持Android与Windows,本质是一个轻应用开发框架,用vue+quasar实现UI,使用极其简单。实现了几个业务代码,比如CRM、会员等,已在码云、CSDN开源。项目还在持续完善中,欢迎使用。
目录
1. 环境问题
1.1. AndroidStudio
1.1.1. 加入jar、aar的方法:
1.1.2. 模拟器路径权限
1.1.3. gradle安装
1.1.4. gradle问题
1.1.5. kotlin、gradle插件被禁用
1.1.6. Kotlin-android not found错误
1.1.7. 修改gradle配置
1.1.8. 打开logcat查看日志
1.1.9. 删除多余import
1.1.10. 修改checkstyle规则
1.1.11. 修改工程名称
1.1.12. adb覆盖安装
1.1.13. 导入样例工程时需要修改的地方
1.1.14 修改项目applicationId
1.1.15 proguard保留所有公共构造函数
1.2. 模拟器
1.2.1. 模拟器IP及外部访问
1.2.2. 进入模拟器命令行
1.3. 网络
1.3.1. 手机与PC之间网络不通
1.3.2. PC不能ping手机
1.3.3. 同局域网下手机访问PC
1.4. 小米手机
1.4.1. 小米手机,无法打开usb安装
1.4.2. 真机进入开发者模式
1.5. 华为或荣耀手机
1.5.1. 打开debug级别日志
1.6. iOS
1.6.1. IPhone webserver备忘
1.7. Eclipse
1.7.1. 更换包名
1.7.2. js(vue)支持
1.8. Gradle
1.8.1. asset下以下划线“_”开头的目录被忽略
1.9. Java
1.9.1. Windows安装GraalVm
1.9.2 Linux下安装GraalVm
1.10.Linux环境
1.10.1.创建用户
1.10.2.端口转发
1.10.3.图片验证码需要安装字体
1.11 Oppo
1.11.1 JUnit单元测试
2. 安卓开发问题
2.1. 权限
2.1.1. 应用权限设置
2.2. 底层
2.2.1. 动态加载dex插件
2.2.2. 实现禁止手动删除数据
2.2.3. 定义安全策略
2.2.4. 依赖了kotlin编写的库
2.3. 安全
2.3.1. 可信根加解密
2.3.2. 添加自签名根证书
2.4. JUnit测试
2.4.1. Android-Unit中无法写文件
2.4.2. 测试准备与清理
2.4.3 测试中加载文件资源
2.5.1. 配置中的属性
2.5.2. DATA_DIR等内置属性未定义
2.6. 版本发布
2.6.1. 应用签名
2.6.2. 图标不更新
2.7 进程间共享SharedPreferences
3. C#开发问题
3.1. 目录权限
3.2. DEBUG宏
3.3. Log4net输出文件路径
3.4. 嵌入资源文件
3.5. 单元测试
3.6. setup工程配置
3.7. 混淆
4. Hybrid
4.1. 框架
4.2. 禁止选中文字
4.3. 引用component
4.4. 生成二维码
5. 数据库
5.1 Sqlite算不算数据库
5.2 Sqlite并发写问题
6. 常识
6.1. 统一信用码编码规则及校验
6.2. 行政区划编号
6.3. Git命令集
1. 环境问题
1.1. AndroidStudio
1.1.1. 加入jar、aar的方法:
a)在app下创建目录libs
b)在app\build.grale中增加implementation fileTree(dir: 'libs', include : ['*.jar','*.aar'])
c)将jar、aar文件拷贝到下面;
d)如果AndroidStudio不能识别,则点击菜单File->Invalidate caches/Restart,然后等等重启即可;
1.1.2. 模拟器路径权限
如果手动在AndroidStudio的Device File Explore中创建路径、文件,会导致在app中无权限访问,必须在App中自己创建。
1.1.3. gradle安装
- 解压到指定路径;
- 配置GRADLE_HOME指向该路径;
- 在路径下创建user目录,配置GRADLE_USER_HOME为%GRADLE_HOME%\user,用于存放临时文件;
- 将%GRADLE_HOME%\bin加入PATH变量
- AndroidStudio的File->Settings中搜索Gradle,设置Gradle路径及GradleUser路径;
- 如果升级gradle,建议下载后,仍然解压到相同路径,这样所有应用的设置不用变动。
1.1.4. gradle问题
工程目录下build.gradle中指定的是AndroidStudio的gradle的版本,可能是适配器,尽量不要改,或者改成AndroidStudio的版本;
gradle\wrapper\gradle-wrapper.properties指定gradle版本,路径可以写成本地下载的zip文件,比如file\:///本地路径,所以这个目录下gradle的zip文件不可以删除。这样可以避免不同的工程都下载一遍。
1.1.5. kotlin、gradle插件被禁用
这两个插件是不可以禁用的,如果禁用,AndroidStudio启动会异常。
这时可以在disabled_plugins.txt中删除相应记录即可,位置如下:
C:\Users\用户名\AppData\Roaming\Google\AndroidStudio4.1\disabled_plugins.txt
1.1.6. Kotlin-android not found错误
在项目build.gradle中删除导致错误的行,然后在Tools-Kotlin选择运行Config Kotlin in Project即可。
1.1.7. 修改gradle配置
每次修改gradle文件,会导致无法编译运行工程,这时选择File->Sync Project With Gradle Files后即可。
1.1.8. 打开logcat查看日志
菜单View-Tool Windows中,打开logcat查看日志。
还有其他一些功能也在此目录下;
1.1.9. 删除多余import
菜单 Code-Optimize Imports可以自动删除所有多余的import;或者使用ctrl+alt+’o’热键。
1.1.10. 修改checkstyle规则
在Settings-Inspections中搜索提示的关键词,找到规则,然后勾选或勾除
1.1.11. 修改工程名称
比如将样例工程修改成最终的工程名称,按以下步骤即可完成:
1.关闭Android Studio;
2.修改项目文件夹的名字;
3.修改OldProjectName.iml文件(在项目的根目录的.idea目录下)的名称为新项名称,即OldProjectName.iml修改为NewProjectName.iml;
4.修改.idea/workspace.xml中相应的名称;
5.修改app/build.gradle中的applicationId;
6.然后把该文件中的external.linked.project.id的值也设置为新项目的名称,即 external.linked.project.id=”NewProjectName”;
7.再次打开AndroidStudio即可。
1.1.12. adb覆盖安装
adb install xxx.apk 如果已安装了,此时会提示
Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install xxx without first uninstalling.]
使用adb install -r xxx.apk,可以覆盖安装它,但是仍然保留前面的数据。
1.1.13. 导入样例工程时需要修改的地方
- 修改项目目录下gradle/wrapper/gradle-wrapper.properties中的distributionUrl,将版本改成graddle中已有的版本,不然又要下载个老的;
- 修改项目目录下build.gradle,将ext.kotlin_version改为当前已有的版本,kotlin版本可以在file-settings-plugins中查看;
- 修改项目目录下app/build.gradle,删除buildSdkVersion,使用当前已有的版本,修改compileSdk、targetSdk为AndroidStudio当前最新版本,修改minSdk为合适的版本,注意这三个配置项的名称在新版本的gradle中,末尾不能带Version;
1.1.14 修改项目applicationId
以下操作是在“Android Studio Flamingo | 2022.2.1 Patch 2”中执行的,其他版本可能不同。
在项目根目录的build.gradle中修改applicationId,如果需要generated的包名也跟着改变,还需要修改build.gradle中的namespace。然后在build菜单中选择“Clean project”,然后在File菜单中选择“Sync Project With Gradle files”,一次不行就执行几次。如果还不行就在File菜单中选择“Invalidate Caches”,重启后再同步几次,直到出现generated目录为止。
1.1.15 proguard保留所有公共构造函数
以下例子是保留所有继承了ScriptElement类的子类中的所有公共的构造函数。 注意“...”表示任何的参数个数、任何参数类型,不能用“***”,它表示的是一个任意类型的参数,而不是多个。 -keepclassmembers class * extends cn.zhijian.mesh.frm.config.placeholder.ScriptElement { public <init>(...); }
1.2. 模拟器
1.2.1. 模拟器IP及外部访问
在模拟器内部,宿主机器IP为10.0.0.2,模拟器自身IP为10.0.2.15/127.0.0.1/localhost
如果需要在宿主机中直接访问模拟器内部的TCP端口,需要先做映射。
adb forward tcp:8081 tcp:8080
这样就可以访问 http://localhost:8081/xxxxx,请求会被转到虚拟机的8080端口
1.2.2. 进入模拟器命令行
adb -s emulator-5554 shell
1.3. 网络
1.3.1. 手机与PC之间网络不通
一般是路由器设置有问题,可能在路由器无线设置中开启了AP隔离,使得同一路由器下各个节点之间不可互通。
1.3.2. PC不能ping手机
网络防火墙默认是不会禁用出站请求的,但是如果安装了360,在360的安全防护中心->入口防护体系中,如果选择了局域网防护,则PC无法联通手机。
1.3.3. 同局域网下手机访问PC
首先,PC上需启动web服务;
其次,要在系统防火墙高级设置中,添加入站规则开放相应的端口,比如TCP的8080端口;
最后,如果安装了360,需要在安全防护中心->系统防护体系中,关闭网络安全防火。
1.4. 小米手机
1.4.1. 小米手机,无法打开usb安装
插入一张Sim卡,没用的Sim卡也可以
1.4.2. 真机进入开发者模式
不同型号得手机,包括华为、小米等,都是在设置的安卓版本上多次点击,即可进入开发者模式。进入开发者模式后,才可以打开USB调试。
1.5. 华为或荣耀手机
1.5.1. 打开debug级别日志
华为手机默认日志级别是info,无论AndroidStudio中设置的是什么,如果要打开debug级别,按以下步骤设置。
1.拨号界面拨号*#*#2846579#*#*可以看到工程菜单;
2.选择后台设置进入;
3.打开 LOG设置,选择 AP日志;
4.回到AndroidStudio中,改变一下日志级别,就可以看到debug了;
5.如果还是无法显示,但是adb logcat -d可以查看,则重启以下AndroidStudio即可。
1.6. iOS
1.6.1. IPhone webserver备忘
基于SwiftNio开发webserver,SwiftNio是iOS中的netty。
https://www.5axxw/wiki/content/zdz096https://www.5axxw/wiki/content/zdz096
其他的如GCDWebServer、CocoaHttpServer都已长期无更新
1.7. Eclipse
1.7.1. 更换包名
在包上点右键,选择Refactor,出现更名窗口,输入新的名称,一定要选择Rename subpackages,否则只会新建一个空的包
1.7.2. js(vue)支持
已有的vue插件已经不维护了,插件wild web develop声称可以支持vue,实际安装后,可以满足工作的基本要求。在eclipse中help->Eclipse Marketplace中搜索javascript,图标是wwd的那个就是,点击安装,重启eclipse后,右键打开js或vue文件,选择“Generic TextEditor”,以后直接双击文件就行了,自动使用Generic TextEditor打开。
1.8. Gradle
1.8.1. asset下以下划线“_”开头的目录被忽略
在项目的gradle文件的android下添加以下配置,将此功能关闭掉
aaptOptions{
ignoreAssetsPattern '!._'
}
1.9. Java
1.9.1. Windows安装GraalVm
下载安装:与java配置完全相同,解压后,在系统的高级配置中添加JAVA_HOME。并将%JAVA_HOME%\bin设置到系统变量path中
安装native-image:gu install native-image
安装llvm:gu install llvm-toolchain
安装js引擎:gu install js
原生编译命令:native-image 或者gradle nativeCompile
Js插件下载(选择正确的版本,注意下载jar格式的):
Releases · oracle/graaljs · GitHubA ECMAScript 2022 compliant JavaScript implementation built on GraalVM. With polyglot language interoperability support. Running Node.js applications! - Releases · oracle/graaljshttps://github/oracle/graaljs/releases
Release GraalVM Community Edition 22.3.2 · graalvm/graalvm-ce-builds · GitHubGraalVM CE binaires built by the GraalVM community - Release GraalVM Community Edition 22.3.2 · graalvm/graalvm-ce-buildshttps://github/graalvm/graalvm-ce-builds/releases/tag/vm-22.3.2
下载的版本号必须与graalvm一致,graalvm版本通过 java -version查看
1.9.2 Linux下安装GraalVm
- 下载以下两个文件,上传到linux服务上;
graalvm-ce-java11-linux-amd64-22.3.1.tar.gz
如果不用内嵌的js支持,可以不用安装js
js-installable-svm-java11-linux-amd64-22.3.2.jar
如果不作原生编译,可以不安装native-image
native-image-installable-svm-svmee-java11-windows-amd64-22.3.2.jar
插件安装命令 gu install js 或者native-image,安装包是从github下载的,所以很慢,并且经常下到一半时提示下载失败,所以找到github网站,直接用迅雷下载到本地后(一定要注意,下载amd的jar文件),再用命令行从本地安装。
gu install -L 本地安装文件 js
- 解压graalvm;
tar xfz graalvm-ce-java11-linux-amd64-22.3.1.tar.gz
【注意】不要解压在/root下,因为这个目录是root用户的根目录,其他用户无法访问
- 并在/etc/profile中增加以下配置
export JAVA_HOME=解压路径
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
- 安装js支持,通过-L选项选择本地安装。
gu install -L js-installable-svm-java11-linux-amd64-22.3.1.jar
不要使用gu install js,因为国内访问github不顺畅,安装极难成功,所以用下载工具(比如迅雷)下载后再在本地安装。
1.10.Linux环境
1.10.1.创建用户
用root用户安装服务是个坏习惯,特别是对外保留接口的服务,一旦有漏洞,黑客获取的就是root权限,所以另建用户安装服务。
useradd -m mesh
-m参数要求系统在/home下自动创建用户目录,mesh为用户名称
passwd mesh
为用户设置一个密码
1.10.2.端口转发
服务程序运行在8523端口,需要将80与443都转发到这个端口,用iptables添加转发规则就可以实现。
1.首先安装iptables,如果已安装,开启它就可以了;
//systemctl stop firewalld # 关闭防火墙
yum -y install iptables-services # 安装 iptables 服务
systemctl enable iptables # 设置 iptables 服务开机启动
systemctl start iptables # 启动 iptables 服务
service iptables save # 保存 iptables 配置
service iptables restart # 重启 iptables 服务
2.开放端口;
iptables服务启动后,默认禁止了1024以上的端口,所以必须打开
iptables -I INPUT -p tcp --dport 8523 -j ACCEPT
3.然后添加端口转发规则;
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8523
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8523
4.查看某个端口的转发规则
iptables -t nat -L -n | grep 80
5.删除端口转发规则
iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8523
6.最后,保存规则。
service iptables save
这样在80与443端口都可以访问。
1.10.3.图片验证码需要安装字体
Linux下生成图片验证码,在FontManagerFactory出现中异常,是因为没有安装字体。使用以下命令安装:
yum -y install fontconfig
fc-list查看已安装的字体
1.11 Oppo
1.11.1 JUnit单元测试
除了要开启USB调试开关外,禁止权限监控的选项不能关闭,否则所有需要存储、网络等的权限申请都会被禁止
2. 安卓开发问题
2.1. 权限
2.1.1. 应用权限设置
在AndroidMenifest.xml中设置,与application同一级别
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
同时,在application中设置android:requestLegacyExternalStorage="true"
2.2. 底层
2.2.1. 动态加载dex插件
- 使用PathClassLoader类加载器实现动态加载dex插件;
- 加载前需要调用dex命令将jar文件转为dex文件,dex文件可以从外部下载获得;
- 因为ClassLoader加载的规则,不同插件不能互访,但是,插件可以访问apk中的类;
2.2.2. 实现禁止手动删除数据
实现一个删除数据的Activity,并在AndroidMenifest.xml-application-android:manageSpaceActivity引用此Acitivity,实现自定义的删除数据管理界面,在此只删除可以删除的,或者全部不删除,比如禁止删除sqlite数据库等。
此Activity的定义与普通Activity毫无差异。
2.2.3. 定义安全策略
在AndroidMenifest.xml-application-android:networkSecurityConfig中可以自定义安全策略,比如预置自签名的根证书等。
2.2.4. 依赖了kotlin编写的库
比如okhttp4.x,提示Failed resolution of: Lkotlin/jvm/internal/Intrinsics,
Kotlin并无特别的优点,建议别用了。现在OkHttp4依赖Kotlin,也用不成了。
2.3. 安全
2.3.1. 可信根加解密
使用KeyStore进行加解密,KeyStore的底层用的是Tee。
它的问题是,在黑屏情况下,无法使用。
EncryptedSharedPreferences 使用的也是KeyStore。
https://source.android.google/security/keystore?hl=zh-cn
2.3.2. 添加自签名根证书
使用CA机构签发证书,通常成本较高,对于一个测试应用,没必要。所以自己产生一个自签名的根证书;然后用根证书产生二级证书;最后用二级证书生成自己的用户证书。这样就形成了一个证书链。在程序中预置根证书,并信任自己的根证书即可。
自签名证书链可以参照以下连接:
KeyTool生成证书链及使用_flyinmind的博客-CSDN博客
以上连接介绍了使用keytool生成根证书、二级证书、三级证书的全部过程。
2.4. JUnit测试
2.4.1. Android-Unit中无法写文件
使用ApplicationProvider.getApplicationContext获得Context,在这个Context中取得的路径是可以读写,写入的内容会存在正式的应用中,而不是在测试的应用中。
2.4.2. 测试准备与清理
在测试函数前加@Before与@After注解,可以控制放在最前面与最后面执行,利用它们做准备与清理工作。
2.4.3 测试中加载文件资源
Java在eclipse中可以将文件放在与java同级的resources目录中,然后使用classloader加载:
InputStream in = XX.class.getClassLoader().getResourceAsStream("fileName");
Junit测试代码所需资源,就放在Junit源码对应目录下的resources目录。
但是在Android studio中不能这样用,必须用context.getAssets().open("fileName")打开输入流,而在JUnit里,重点是怎样获得context,推荐以下方法:
Context context = ApplicationProvider.getApplicationContext();
InputStream in = context.getAssets().open("fileName")
2.5. Logback日志
2.5.1. 配置中的属性
logback读配置文件时,其中用到的属性,用${propertyName}引用。属性需要在初始化的Context中设置,比如指定根路径。此Context不能reset,否则property会丢失。
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
lc.putProperty("loggerHome", outputDir);
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
//lc.reset(); //reset会清除property
configurator.doConfigure(cfgFile);
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
2.5.2. DATA_DIR等内置属性未定义
在一些例子中,出现诸如DATA_DIR、PACKAGE_NAME等属性,其实它们不能用,通过看代码,猜测可能是因为logback获取应用Context的方法有误。所以需要在程序里加载配置前,设置自定义属性,然后在logback.xml中引用。
2.6. 版本发布
2.6.1. 应用签名
版本发布需证书进行签名,这个证书可以使用EC也可以使用RSA,可以用证书链进行签名。Debug情况下,生成了默认的证书,但是发布时不能使用。
Release时,选择菜单Build->Generate Signed Bundle/APK,选择已有的证书或新建一个证书,此证书要伴随应用终身,所以必须保存好,并且记住key密码及store密码。
也可以使用自己签名的证书,生成方法请参考以下连接:
KeyTool生成证书链及使用_flyinmind的博客-CSDN博客
2.6.2. 图标不更新
在“new->image asset”中创建的图标可以保证在不同分辨率下,提供不同的图标,保障合适的清晰度。但是image asset创建的图标与app的工程是独立的,需要将它们拷贝到main的res目录下,并且,不能忘记拷贝mipmap-anydpi-v26或者mipmap-anydpi-v24与values目录,这两个目录不是打酱油的,如果不拷贝它,图标就不会更新,因为安卓里面使用的是mipmap-anydpi-vxx.xml,由它区分不同的分辨率,选择不同的图标。
2.7 进程间共享SharedPreferences
虽然名称中有shared的,其实进程间共享时有诸多问题,最大的问题是不同步。
SharedPreferences第一次打开时会从配置文件中读取k-v对,存到一个map中,后面的变更使用Editor.apply,Editormit写到文件中。如果其他进程也在修改SharedPreferences,当前进程是不能即使感知的,除非重新调用getSharedPreferences:
Context.getSharedPreferences(NAME, Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
注意要设置MODE_MULTI_PROCESS(此标志位已不建议使用了),此标志位只是告诉getSharedPreferences在获得SharedPreferences对象时,重新读取一次文件,并不会保证多进程之间的同步;如果不设置,则直接使用以前曾经打开过的SharedPreferences对象(SharedPreferences也会缓存)。
3. C#开发问题
3.1. 目录权限
应用安装在programs目录下时,程序是无权限写当前路径的,可以通过
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
获得应用可以写入的路径,比如C:\Users\帐号\AppData\Roaming\应用名称。在此路径下可以写入日志、运行时文件等。
3.2. DEBUG宏
代码中可以通过判断DEBUG宏是否定义给出不同的实现。
#if DEBUG
public const string API_DOMAIN = "192.168.0.102";
#else
public const string API_DOMAIN = "api" + CERT_DOMAIN;
#endif
为了使DEBUG生效,还必须右键项目,选择“属性->生成”,在DEBUG配置中,选中“定义DEBUG常数”,否则#if DEBUG判断将失败
3.3. Log4net输出文件路径
与目录权限有关,需要根据运行时情况设置日志输出的根路径,可以设置 GlobalContext.Properties["loggerHome"] = outputDir;
然后在log4net.xml的appender.file中引用loggerHome,形式如下:
<file type="log4net.Util.PatternString" value="%property{loggerHome}\\logs\\mesh\\run.log" />
注意,一定要设type为log4net.Util.PatternString,否则%property{loggerHome}被当成普通字符串解析
3.4. 嵌入资源文件
推荐以文件形式嵌入资源,这样便于直接在文件夹中修改文件,而不必每次修改文件后重新刷新到Resources.resx中
在工程上右键,选择添加->新建文件夹,建立Resources目录,然后在里面添加各种文件,注意,资源的生成操作一定要选择“嵌入的资源”。
然后在程序中,使用如下方式打开资源文件流:
Assembly assm = Assembly.GetExecutingAssembly();
Stream s = assm.GetManifestResourceStream("工程名.Resources." + fileName);
此处的fileName是包括扩展名的。
3.5. 单元测试
首先写单元测试函数,在class上面写 [TestClass],测试函数上写[TestMethod],通过Assert.xxx断言。
然后在视图菜单中打开“测试资源管理器”,一定要选中那个烧瓶形状的图标,然后运行所有测试。单元测试做完之后,建议关闭“测试资源管理器”,它会占用一部分资源。
3.6. setup工程配置
自带的打包工具很别扭,开发了这么多年也没有提升。所以,项目使用inno setup制作安装文件,其中要包括release目录下的dll。在使用webview2的情况下,需要包括runtimes\win-x64\native\WebView2Loader.dll。
如果用打包成中文,在添加ChineseSimplified.isl时,需要转为utf8-with-BOM格式(可以用notepad++修改),否则界面会显示乱码;如果还需要指定license等文件,也同样要改成utf8-with-BOM格式。
3.7. 混淆
使用.Net reactor,选中release下的主程序exe,然后选中obfuscation,对程序进行混淆。混淆之后再用inno settup生成安装包。
4. Hybrid
4.1. 框架
使用vue+vue-router+quasar开发,在浏览器中输出界面,调用底层的接口。
注意:vue要使用vue.global.prod.js版本,不能使用vue.runtime.global.prod.js。
可以从https://cdn.jsdelivr/npm/vue@next/dist/下载。
quasar从https://quasar.dev/start/umd下载,包括quasar.umd.prod.js与quasar.prod.css,这个连接中css可以与quasar.prod.css合并,其中用到的字体也需要逐个下载,放到本地,链接为:
https://fonts.googleapis/css?family=Roboto:100,300,400,500,700,900|Material+Icons
4.2. 禁止选中文字
在游戏的场景中,经常要用到拖动,容易造成文字被选中,这时可以通过在css中增加user-select: none; 来禁止选中文字
4.3. 引用component
1) 引入component文件
import AlertDialog from "/assets/v3/components/alert_dialog.js"
2) 注册component
appponent('component-alert-dialog', AlertDialog);
注册要放在app.mount之前,否则调用component中方法会提示xxx is not a function
3) 在template中引入component
<component-alert-dialog :title="tags.failToCall" :close="tags.close" ref="errDlg"></component-alert-dialog>
4) 在js中调用component
this.$refs.errDlg.show(“xxxx”);
4.4. 生成二维码
因为不是在nodejs中开发,不能用import方式引入qrcodejs2,所以只能在index.html直接包含它:
<script src="/js路径/qrcode.js"></script>
然后,在template中增加一个div,用以容纳二维码,这里用的是相对宽度vw,所以在生成时要计算一下。
<div ref="qrCodeUrl" style="width:60vw; height:60vw;"></div>
最后,在需要显示时调用:
new QRCode(this.$refs.qrCodeUrl, {
text: 'https://www.baidu',
width: document.documentElement.clientWidth * 0.6,
height: document.documentElement.clientWidth * 0.6,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
如果用在dialog中,必须在dialog的@show中调用显示二维码,如果太早了,dialog的元素还没有创建,此时显示就会失败
5. 数据库
5.1 Sqlite算不算数据库
这个问题,我纠结了很久,以前在大厂工作时,跟人提议用sqlite解决一些问题,也是被不耻的。即在我使用了很长时间后,也不好意思跟别人说,我在服务器上是用sqlite代替mysql或其他大型数据库的:(
Sqlite算不算数据库呢,它只是一个单例的小型数据库,难上台面的感觉。但是,我觉得算,并且经常使用,因为在至简网格选择的奇葩而苛刻的场景中,必然不能用大型数据库。
首先从拷贝数量看,它绝对全球领先,因为每部智能机上必有多个拷贝,每个浏览器中必有一份拷贝,它们面临的场景也会千奇百怪。其次,从功能上说,基本的都有。我在其上添加基本的同步能力,在数据量不大的情况下(百万行级的样子),很合适。最后从性能上看,单机直接批量写入,7个字段,上万没问题,即使逐行插入,上千不成问题,查询上3万问题不大,这样的性能足可解决绝大部分问题了。
5.2 Sqlite并发写问题
首先Sqlite不支持并发写入,所以创建连接池时,只能创建一个可写连接;但是它可以支持并发读,所以可以创建多个读连接。如果不小心出现了两个写连接,并且是并发访问,就会出现吊死。所以在连接池维护上一定要小心。
6. 常识
6.1. 统一信用码编码规则及校验
规则:【微科普】教你看懂统一社会信用代码_机构
Java实现:校验社会统一信用代码JAVA_王魂凤气的博客-CSDN博客_校验统一社会信用代码
6.2. 行政区划编号
https://www.mca.gov/article/sj/xzqh/1980/202105/20210500033655.shtml
6.3. Git命令集
请参照这篇文章Git操作备忘_flyinmind的博客-CSDN博客
本文标签: 解决方法
版权声明:本文标题:全栈开发中碰到的一些问题及解决方法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1725919768h892804.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论