Some problems and solutions encountered in full-stack development

        In the process of developing Simple Grid , both server-side development and multi-device development are required. The service side is divided into JAVA service side, Android service side, and the terminal side is divided into Android and Windows. The technology is complicated and many basic problems are encountered. All are recorded here for easy reference in the future.

        By the way, as a small advertisement, Zhijian Grid is a development framework combining device and cloud, which greatly simplifies the development of server side and device side. Using simple json configuration and sql and js scripts on the server side, more than 95% of business scenarios can be handled; the device side supports Android and Windows. Implemented several business codes, such as CRM, membership, etc., which have been open sourced in Code Cloud and CSDN . The project is still in continuous improvement, welcome to use.

Table of contents

1. Environmental issues

1.1. AndroidStudio

1.1.1. How to add jar and aar:

1.1.2. Simulator Path Permissions

1.1.3. gradle installation

1.1.4. gradle problems

1.1.5. kotlin, gradle plugin is disabled

1.1.6. Kotlin-android not found error

1.1.7. Modify the gradle configuration

1.1.8. Open logcat to view logs

1.1.9. Delete redundant imports

1.1.10. Modify checkstyle rules

1.1.11. Modify project name

1.1.12. adb overlay installation

1.1.13. What needs to be modified when importing the sample project

1.1.14 Modify project applicationId

1.2. Simulator

1.2.1. Simulator IP and external access

1.2.2. Enter the emulator command line

1.3. Network

1.3.1. The network between the mobile phone and the PC is disconnected

1.3.2. The PC cannot ping the mobile phone

1.3.3. Mobile phone access PC under the same LAN

1.4. Mi phone

1.4.1. Xiaomi mobile phone, unable to open usb installation

1.4.2. Real device enters developer mode

1.5. Huawei or Honor mobile phone

1.5.1. Open debug level log

1.6.             iOS

1.6.1. IPhone webserver notes

1.7.             Eclipse

1.7.1. Change the package name

1.8.          Gradle

1.8.1. The directory under the asset that starts with an underscore "_" is ignored

1.9.          Java

1.9.1. Install GraalVm on Windows

1.9.2 Install GraalVm under Linux

1.10. Linux environment

1.10.1. Create user

1.10.2. Port Forwarding

​​​​​​1.10.3. Image verification code needs to install fonts

2. Android development issues

2.1. Permissions

2.1.1. App permission setting

2.2. Bottom layer

2.2.1. Dynamic loading of dex plugins

2.2.2. Realize the prohibition of manual deletion of data

2.2.3. Define Security Policy

2.2.4. Depends on libraries written in kotlin

2.3. Security

2.3.1. Root of Trust Encryption and Decryption

2.3.2. Add self-signed root certificate

2.4. JUnit test

2.4.1. Unable to write files in Android-Unit

2.4.2. Test preparation and cleanup

2.5. Logback logs

2.5.1. Properties in configuration

2.5.2. Built-in properties such as DATA_DIR are undefined

2.6. Version release

2.6.1. Application Signature

2.6.2. Icon not updating

3. C# development problem

3.1. Directory permissions

3.2. Log4net output file path

3.3. Embed resource files

3.4. Unit testing

3.5. setup project configuration

3.6. Obfuscation

4.   Hybrid

4.1. Framework

4.2. Disable text selection

4.3. Reference component

4.4. Generate QR code

5. Common sense

5.1. Unified credit code coding rules and verification

5.2. Administrative division number

5.3. Git command set


1. Environmental issues

1.1. AndroidStudio

1.1.1. How to add jar and aar:

a) Create directory libs under app

b) Add implementation fileTree(dir: 'libs', include : ['*.jar','*.aar']) in app\build.grale

c) Copy the jar and aar files to the following;

d) If AndroidStudio can't recognize it, click the menu File->Invalidate caches/Restart, and then restart it;

1.1.2. Simulator Path Permissions

If you manually create paths and files in AndroidStudio's Device File Explore, it will result in unauthorized access in the app, and you must create them yourself in the app.

1.1.3. gradle installation

  1.       Unzip to the specified path;
  2.      Configure GRADLE_HOME to point to this path;
  3.       Create a user directory under the path, and configure GRADLE_USER_HOME as %GRADLE_HOME%\user to store temporary files;
  4.      Add %GRADLE_HOME%\bin to PATH variable
  5.       Search for Gradle in File->Settings of AndroidStudio, set the Gradle path and GradleUser path;
  6.        If you upgrade gradle, it is recommended to unzip it to the same path after downloading, so that the settings of all applications do not need to be changed.

1.1.4. gradle problems

The build.gradle in the project directory specifies the gradle version of AndroidStudio, which may be an adapter, try not to change it, or change it to the version of AndroidStudio;

gradle\wrapper\gradle-wrapper.properties specifies the gradle version, and the path can be written as a locally downloaded zip file, such as file\:///local path, so the gradle zip file in this directory cannot be deleted. This can avoid downloading different projects all over again.

1.1.5. kotlin, gradle plugin is disabled

These two plug-ins cannot be disabled. If disabled, AndroidStudio will start abnormally.

At this time, you can delete the corresponding record in disabled_plugins.txt, the location is as follows:

C:\Users\用户名\AppData\Roaming\Google\AndroidStudio4.1\disabled_plugins.txt

1.1.6. Kotlin-android not found error

Delete the line that causes the error in the project build.gradle, and then choose to run Config Kotlin in Project in Tools-Kotlin.

1.1.7. Modify the gradle configuration

Every time the gradle file is modified, the project cannot be compiled and run. In this case, select File->Sync Project With Gradle Files.

1.1.8. Open logcat to view logs

In the menu View-Tool Windows, open logcat to view the log.

There are some other functions also under this directory;

1.1.9. Delete redundant imports

The menu Code-Optimize Imports can automatically delete all redundant imports; or use the ctrl+alt+'o' hotkey.

1.1.10. Modify checkstyle rules

Search for the suggested keywords in Settings-Inspections, find the rules, and check or uncheck them

1.1.11. Modify project name

For example, to modify the sample project to the final project name, follow the steps below to complete:

1. Close Android Studio;

2. Modify the name of the project folder;

3. Modify the name of the OldProjectName.iml file (in the .idea directory of the root directory of the project) to the new item name, that is, change OldProjectName.iml to NewProjectName.iml;

4. Modify the corresponding name in .idea/workspace.xml;

5. Modify the applicationId in app/build.gradle;

6. Then set the value of external.linked.project.id in the file to the name of the new project, ie external.linked.project.id="NewProjectName";

7. Just open AndroidStudio again.

1.1.12. adb overlay installation

adb install xxx.apk If it is already installed, it will prompt

Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install xxx without first uninstalling.]

Using adb install -r xxx.apk, you can overwrite and install it, but still retain the previous data.

1.1.13. What needs to be modified when importing the sample project

  1. Modify the distributionUrl in gradle/wrapper/gradle-wrapper.properties in the project directory, and change the version to the existing version in graddle, or download an old one;
  2. Modify build.gradle in the project directory, and change ext.kotlin_version to the current version. The kotlin version can be viewed in file-settings-plugins;
  3. Modify app/build.gradle in the project directory, delete buildSdkVersion, use the current existing version, modify compileSdk and targetSdk to the latest version of AndroidStudio, and modify minSdk to an appropriate version. Note that the names of these three configuration items are in the new version of gradle, and Version cannot be added at the end;

1.1.14 Modify project applicationId

        The following operations are performed in "Android Studio Flamingo | 2022.2.1 Patch 2", other versions may be different.

        Modify the applicationId in build.gradle in the root directory of the project. If you need to change the generated package name, you also need to modify the namespace in build.gradle. Then select "Clean project" in the build menu, then select "Sync Project With Gradle files" in the File menu, and execute it several times if it doesn't work once. If it still doesn't work, select "Invalidate Caches" in the File menu, restart and then synchronize several times until the generated directory appears.

1.2. Simulator

1.2.1. Simulator IP and external access

Inside the simulator, the IP of the host machine is 10.0.0.2, and the IP of the simulator itself is 10.0.2.15/127.0.0.1/localhost

If you need to directly access the TCP port inside the emulator in the host, you need to do mapping first.

adb forward tcp:8081 tcp:8080

In this way , http://localhost:8081/xxxxx can be accessed  , and the request will be forwarded to port 8080 of the virtual machine

1.2.2. Enter the emulator command line

adb -s emulator-5554 shell

1.3. Network

1.3.1. The network between the mobile phone and the PC is disconnected

Generally, there is a problem with the router settings. AP isolation may be enabled in the wireless settings of the router, so that the nodes under the same router cannot communicate with each other.

1.3.2. The PC cannot ping the mobile phone

The network firewall does not disable outbound requests by default, but if 360 is installed, in 360's security protection center -> ingress protection system, if LAN protection is selected, the PC cannot communicate with the mobile phone.

1.3.3. Mobile phone access PC under the same LAN

First, the web service needs to be started on the PC;

Secondly, in the advanced settings of the system firewall, add inbound rules to open the corresponding ports, such as port 8080 of TCP;

Finally, if 360 is installed, you need to turn off the network security fire protection in the security protection center -> system protection system.

1.4. Mi phone

1.4.1. Xiaomi mobile phone, unable to open usb installation

Insert a Sim card, useless Sim card is also ok

1.4.2. Real device enters developer mode

Different models of mobile phones, including Huawei, Xiaomi, etc., can enter the developer mode by clicking multiple times on the set Android version. After entering the developer mode, you can enable USB debugging.

1.5. Huawei or Honor mobile phone

1.5.1. Open debug level log

The default log level of Huawei mobile phones is info, no matter what is set in AndroidStudio, if you want to open the debug level, follow the steps below to set it.

1. Dial *#*#2846579#*#* on the dial interface to see the project menu;

2. Select background settings to enter;

3. Open LOG settings, select AP log;

4. Go back to AndroidStudio, change the log level, and you can see debug;

5. If it still cannot be displayed, but adb logcat -d can be viewed, restart AndroidStudio as follows.

1.6.             iOS

1.6.1. IPhone webserver notes

Develop webserver based on SwiftNio, which is netty in iOS.

https://www.5axxw.com/wiki/content/zdz096https://www.5axxw.com/wiki/content/zdz096

Others such as GCDWebServer and CocoaHttpServer have not been updated for a long time

1.7.             Eclipse

1.7.1. Change the package name

Right-click on the package, select Refactor, a rename window appears, enter a new name, be sure to select Rename subpackages, otherwise it will only create an empty package

1.8.          Gradle

1.8.1. The directory under the asset that starts with an underscore "_" is ignored

Add the following configuration under android in the project's gradle file to turn off this function

aaptOptions{
    ignoreAssetsPattern '!._'
}

1.9.          Java

1.9.1. Install GraalVm on Windows

Download and install: exactly the same as the java configuration, after decompression, configure JAVA_HOME and set bin to the system variable path

Anso native-image: gu install native-image

安装llvm:gu install llvm-toolchain

Install the js engine: gu install js

Native compilation command: native-image

1.9.2  Install GraalVm under Linux

  1. Download the following two files and upload them to the linux service;

graalvm-ce-java11-linux-amd64-22.3.1.tar.gz

js-installable-svm-java11-linux-amd64-22.3.1.jar

  1. unzip graalvm;

tar xfz graalvm-ce-java11-linux-amd64-22.3.1.tar.gz

[Note] Do not unzip it under /root, because this directory is the root directory of the root user, and other users cannot access it

  1. And add the following configuration in /etc/profile

export JAVA_HOME=Decompression path

export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

export PATH=${JAVA_HOME}/bin:$PATH

  1. Install js support, select local installation through the -L option.

gu install -L js-installable-svm-java11-linux-amd64-22.3.1.jar

Do not use gu install js, because the domestic access to github is not smooth, and the installation is extremely difficult to succeed, so download it with a download tool (such as Thunder) and install it locally.

1.10. Linux environment


1.10.1. Create user


It is a bad habit to use the root user to install services, especially for services that retain external interfaces. Once there is a loophole, hackers can obtain root privileges, so another user installation service is created.
useradd -m mesh
-m parameter requires the system to automatically create a user directory under /home, mesh is the user name
passwd mesh
is the user to set a password


1.10.2. Port Forwarding


The service program runs on port 8523, and both 80 and 443 need to be forwarded to this port, which can be realized by adding forwarding rules with iptables.


1. First install iptables, if it is already installed, open it;
//systemctl stop firewalld # Close the firewall
yum -y install iptables-services # Install iptables service
systemctl enable iptables # Set iptables service boot
systemctl start iptables # Start iptables service
service iptables save # Save iptables configuration
service iptables restart # Restart iptables service

2. Open ports;
After the iptables service is started, ports above 1024 are disabled by default, so you must open
iptables -I INPUT -p tcp --dport 8523 -j ACCEPT

3. Then add port forwarding rules;
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. View the forwarding rules of a port
iptables -t nat -L -n | grep 80

5. Delete the port forwarding rule
iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8523

6. Finally, save the rule.
service iptables save

In this way, both ports 80 and 443 can be accessed.

​​​​​​1.10.3. Image verification code needs to install fonts

The picture verification code is generated under Linux, and an exception occurs in FontManagerFactory because the font is not installed. Install with the following command:

yum -y install fontconfig

fc-list view installed fonts

2. Android development issues

2.1. Permissions

2.1.1. App permission setting

Set in AndroidMenifest.xml, same level as 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" />

At the same time, set android:requestLegacyExternalStorage="true" in the application

2.2. Bottom layer

2.2.1. Dynamic loading of dex plugins

  1. Use the PathClassLoader class loader to dynamically load the dex plugin;
  2. Before loading, you need to call the dex command to convert the jar file into a dex file, and the dex file can be downloaded from the outside;
  3. Because of the rules loaded by ClassLoader, different plug-ins cannot access each other, but plug-ins can access classes in apk;

2.2.2. Realize the prohibition of manual deletion of data

Implement an Activity that deletes data, and reference this Activity in AndroidMenifest.xml-application-android:manageSpaceActivity, and implement a custom deletion data management interface. Here, only deleteable data can be deleted, or not deleted at all, such as prohibiting the deletion of sqlite databases, etc.

The definition of this Activity is no different from that of a normal Activity.

2.2.3. Define Security Policy

Security policies can be customized in AndroidMenifest.xml-application-android:networkSecurityConfig, such as pre-installed self-signed root certificates, etc.

2.2.4. Depends on libraries written in kotlin

For example, okhttp4.x prompts Failed resolution of: Lkotlin/jvm/internal/Intrinsics,

Kotlin has no special advantages, so it is recommended not to use it. Restricting OkHttp4 to rely on Kotlin is also useless.

2.3. Security

2.3.1. Root of Trust Encryption and Decryption

Use KeyStore for encryption and decryption, and the bottom layer of KeyStore uses Tee.

The problem with it is that it cannot be used when the screen is black.

EncryptedSharedPreferences also uses KeyStore.

https://source.android.google.cn/security/keystore?hl=zh-cn

2.3.2. Add self-signed root certificate

The cost of using a CA to issue a certificate is usually high, and it is not necessary for a test application. So generate a self-signed root certificate yourself; then use the root certificate to generate a secondary certificate; finally use the secondary certificate to generate your own user certificate. This forms a certificate chain. Preset the root certificate in the program and trust your own root certificate.

The self-signed certificate chain can refer to the following link:

KeyTool generates a certificate chain and uses it_flyinmind's Blog-CSDN Blog

The above link introduces the whole process of using keytool to generate root certificate, secondary certificate and tertiary certificate.

2.4. JUnit test

2.4.1. Unable to write files in Android-Unit

Use ApplicationProvider.getApplicationContext to get the Context. The path obtained in this Context can be read and written, and the written content will exist in the official application, not in the test application.

2.4.2. Test preparation and cleanup

Adding @Before and @After annotations before the test function can control the execution at the front and the end, and use them to prepare and clean up.

2.5. Logback logs

2.5.1. Properties in configuration

When logback reads the configuration file, the properties used in it are referenced by ${propertyName}. Properties need to be set in the initialized Context, such as specifying the root path. This Context cannot be reset, otherwise the property will be lost.

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. Built-in properties such as DATA_DIR are undefined

In some examples, attributes such as DATA_DIR and PACKAGE_NAME appear, but they cannot be used. By looking at the code, it is guessed that the method for logback to obtain the application context may be wrong. Therefore, you need to set custom properties before loading the configuration in the program, and then reference them in logback.xml.

2.6. Version release

2.6.1. Application Signature

The release of the version requires a certificate to be signed. This certificate can use EC or RSA, and can be signed with a certificate chain. In the case of Debug, a default certificate is generated, but do not use it when publishing.

During Release, select the menu Build->Generate Signed Bundle/APK, select an existing certificate or create a new one. This certificate must accompany the application for life, so it must be kept well, and remember the key password and store password.

You can also use a self-signed certificate. For the generation method, please refer to the following link:

KeyTool generates a certificate chain and uses it_flyinmind's Blog-CSDN Blog

2.6.2. Icon not updating

The icons created in "new->image asset" can provide different icons at different resolutions to ensure appropriate clarity. But the icon created by image asset is independent of the app project, you need to copy them to the main res directory, and don’t forget to copy the mipmap-anydpi-v26 or mipmap-anydpi-v24 and values ​​directory, these two directories are not soy sauce, if you don’t copy it, the icon will not be updated, because Android uses mipmap-anydpi-vxx.xml, which distinguishes different resolutions and selects different icons.

3. C# development problem

3.1. Directory permissions

When the application is installed in the programs directory, the program has no permission to write the current path, you can pass

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

Obtain the path that the application can write to, such as C:\Users\Account\AppData\Roaming\Application Name. Logs, runtime files, etc. can be written to this path.

3.2. Log4net output file path

Related to directory permissions, you need to set the root path of the log output according to the runtime situation, you can set GlobalContext.Properties["loggerHome"] = outputDir;

Then refer to loggerHome in appender.file of log4net.xml in the following form:

<file type="log4net.Util.PatternString" value="%property{loggerHome}\\logs\\mesh\\run.log" />

Note that type must be set to log4net.Util.PatternString, otherwise %property{loggerHome} will be parsed as a normal string

3.3. Embed resource files

It is recommended to embed resources in the form of files, so that it is convenient to modify the files directly in the folder, without having to refresh to Resources.resx after each file modification

Right-click on the project, select Add -> New Folder, create a Resources directory, and then add various files in it. Note that the resource generation operation must select "embedded resources".

Then in the program, use the following method to open the resource file stream:

Assembly assm = Assembly.GetExecutingAssembly();

Stream s = assm.GetManifestResourceStream("Project name.Resources." + fileName);

The fileName here includes the extension.

3.4. Unit testing

First write the unit test function, write [TestClass] on the class, write [TestMethod] on the test function, and assert through Assert.xxx.

Then open the "Test Explorer" in the view menu, make sure that the flask-shaped icon is selected, and run all the tests.

3.5. setup project configuration

        The packaging tool that comes with .net is very awkward, and it has not been improved after so many years of development. Therefore, the project uses inno setup to make installation files, which must include the dll in the release directory. In the case of using webview2, runtimes\win-x64\native\WebView2Loader.dll needs to be included.

        If it is packaged into Chinese, when adding ChineseSimplified.isl, it needs to be converted to utf8-with-BOM format (can be modified with notepad++), otherwise the interface will display garbled characters; if it is necessary to specify license and other files, it must also be changed to utf8-with-BOM format.

3.6. Obfuscation

        Use .Net reactor, select the main program exe under release, and then select obfuscation to confuse the program. After confusion, use inno settup to generate the installation package.

4.   Hybrid

4.1. Framework

Use vue+vue-router+quasar to develop, output the interface in the browser, and call the underlying interface.

Note: vue needs to use vue.global.prod.js version instead of vue.runtime.global.prod.js .

It can be downloaded from https://cdn.jsdelivr.net/npm/vue@next/dist/.

Download quasar from https://quasar.dev/start/umd, including quasar.umd.prod.js and quasar.prod.css. In this connection, css can be merged with quasar.prod.css. The fonts used in it also need to be downloaded one by one and put locally. The link is:

https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons

4.2. Disable text selection

In the game scene, dragging is often used, and it is easy to cause the text to be selected. At this time, you can add user-select: none; to the css to prohibit the text from being selected

4.3. Reference component

1) Import component file

import AlertDialog from "/assets/v3/components/alert_dialog.js"

2) Register the component

app.component('component-alert-dialog', AlertDialog);

The registration should be placed before app.mount, otherwise calling the method in the component will prompt xxx is not a function

3) Introduce the component in the template

<component-alert-dialog :title="tags.failToCall" :close="tags.close" ref="errDlg"></component-alert-dialog>

4) Call component in js

this.$refs.errDlg.show(“xxxx”);

4.4. Generate QR code

Because it is not developed in nodejs, qrcodejs2 cannot be introduced by import, so it can only be included directly in index.html:

<script src="/js path/qrcode.js"></script>

Then, add a div to the template to accommodate the QR code. The relative width vw is used here, so it needs to be calculated when generating it.

<div ref="qrCodeUrl" style="width:60vw; height:60vw;"></div>

Finally, call when you need to display:

new QRCode(this.$refs.qrCodeUrl, {

    text: 'https://www.baidu.com',

    width: document.documentElement.clientWidth * 0.6,

    height: document.documentElement.clientWidth * 0.6,

    colorDark: '#000000',

    colorLight: '#ffffff',

    correctLevel: QRCode.CorrectLevel.H

});

If it is used in a dialog, it must be called to display the QR code in the @show of the dialog. If it is too early, the element of the dialog has not been created, and the display will fail at this time.

5. Common sense

5.1. Unified credit code coding rules and verification

Rules: [Micro Science Popularization] Teach you to understand the unified social credit code_Organization

Java Implementation: Verifying the Social Unified Credit CodeJAVA

5.2. Administrative division number

https://www.mca.gov.cn/article/sj/xzqh/1980/202105/20210500033655.shtml

5.3. Git command set

Please refer to this article Git operation notes_flyinmind's blog-CSDN blog

Guess you like

Origin blog.csdn.net/flyinmind/article/details/126965194