android cocoscreator 检测模拟器还是真机

news2025/1/21 4:57:32

转载至 一行代码帮你检测Android模拟器   

具体原理看原博主文章,这里只讲cocoscreator3.6的安卓工程怎么使用

1.新建一个com.lahm.library包,和com.cocos.game同目录,如图示

那四个文件的代码如下:

EmulatorCheckUtil类,检测模拟器和真机的工具类,是入口:

package com.lahm.library;

import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.internal.LockOnGetVariable;

import static android.content.Context.SENSOR_SERVICE;
import static com.lahm.library.CheckResult.RESULT_EMULATOR;
import static com.lahm.library.CheckResult.RESULT_MAYBE_EMULATOR;
import static com.lahm.library.CheckResult.RESULT_UNKNOWN;

/**
 * Project Name:检查是否是模拟器
 * Package Name:com.lahm.library
 * Created by lahm on 2018/6/8 15:01 .
 */
public class EmulatorCheckUtil {
    private static String TAG = "EmulatorCheckUtil:";
    private EmulatorCheckUtil() {

    }

    private static class SingletonHolder {
        private static final EmulatorCheckUtil INSTANCE = new EmulatorCheckUtil();
    }

    public static final EmulatorCheckUtil getSingleInstance() {
        return SingletonHolder.INSTANCE;
    }

    public boolean readSysProperty(Context context, EmulatorCheckCallback callback) {
        if (context == null)
            throw new IllegalArgumentException("context must not be null");

        int suspectCount = 0;

        //检测硬件名称
        CheckResult hardwareResult = checkFeaturesByHardware();
        switch (hardwareResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("hardware = " + hardwareResult.value);
                return true;
        }

        //检测渠道
        CheckResult flavorResult = checkFeaturesByFlavor();
        switch (flavorResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("flavor = " + flavorResult.value);
                return true;
        }

        //检测设备型号
        CheckResult modelResult = checkFeaturesByModel();
        switch (modelResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("model = " + modelResult.value);
                return true;
        }

        //检测硬件制造商
        CheckResult manufacturerResult = checkFeaturesByManufacturer();
        switch (manufacturerResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null)
                    callback.findEmulator("manufacturer = " + manufacturerResult.value);
                return true;
        }

        //检测主板名称
        CheckResult boardResult = checkFeaturesByBoard();
        switch (boardResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("board = " + boardResult.value);
                return true;
        }

        //检测主板平台
        CheckResult platformResult = checkFeaturesByPlatform();
        switch (platformResult.result) {
            case RESULT_MAYBE_EMULATOR:
                ++suspectCount;
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("platform = " + platformResult.value);
                return true;
        }

        //检测基带信息
        CheckResult baseBandResult = checkFeaturesByBaseBand();
        switch (baseBandResult.result) {
            case RESULT_MAYBE_EMULATOR:
                suspectCount += 2;//模拟器基带信息为null的情况概率相当大
                break;
            case RESULT_EMULATOR:
                if (callback != null) callback.findEmulator("baseBand = " + baseBandResult.value);
                return true;
        }

        //检测传感器数量
        int sensorNumber = getSensorNumber(context);
        if (sensorNumber <= 7) ++suspectCount;

        //检测已安装第三方应用数量
        int userAppNumber = getUserAppNumber();
        if (userAppNumber <= 5) ++suspectCount;

        //检测是否支持闪光灯
        boolean supportCameraFlash = supportCameraFlash(context);
        if (!supportCameraFlash) ++suspectCount;
        //检测是否支持相机
        boolean supportCamera = supportCamera(context);
        if (!supportCamera) ++suspectCount;
        //检测是否支持蓝牙
        boolean supportBluetooth = supportBluetooth(context);
        if (!supportBluetooth) ++suspectCount;

        //检测光线传感器
        boolean hasLightSensor = hasLightSensor(context);
        if (!hasLightSensor) ++suspectCount;

        //检测进程组信息
        CheckResult cgroupResult = checkFeaturesByCgroup();
        if (cgroupResult.result == RESULT_MAYBE_EMULATOR) ++suspectCount;

        if (callback != null) {
            StringBuffer stringBuffer = new StringBuffer("Test start")
                    .append("\r\n").append("hardware = ").append(hardwareResult.value)
                    .append("\r\n").append("flavor = ").append(flavorResult.value)
                    .append("\r\n").append("model = ").append(modelResult.value)
                    .append("\r\n").append("manufacturer = ").append(manufacturerResult.value)
                    .append("\r\n").append("board = ").append(boardResult.value)
                    .append("\r\n").append("platform = ").append(platformResult.value)
                    .append("\r\n").append("baseBand = ").append(baseBandResult.value)
                    .append("\r\n").append("sensorNumber = ").append(sensorNumber)
                    .append("\r\n").append("userAppNumber = ").append(userAppNumber)
                    .append("\r\n").append("supportCamera = ").append(supportCamera)
                    .append("\r\n").append("supportCameraFlash = ").append(supportCameraFlash)
                    .append("\r\n").append("supportBluetooth = ").append(supportBluetooth)
                    .append("\r\n").append("hasLightSensor = ").append(hasLightSensor)
                    .append("\r\n").append("cgroupResult = ").append(cgroupResult.value)
                    .append("\r\n").append("suspectCount = ").append(suspectCount);
            callback.findEmulator(stringBuffer.toString());
        }
        Log.i(TAG, "EmulatorCheck suspectCount:" + suspectCount);
        //嫌疑值大于3,认为是模拟器
        return suspectCount >= 3;
    }

    private int getUserAppNum(String userApps) {
        if (TextUtils.isEmpty(userApps)) return 0;
        String[] result = userApps.split("package:");
        return result.length;
    }

    private String getProperty(String propName) {
        String property = CommandUtil.getSingleInstance().getProperty(propName);
        return TextUtils.isEmpty(property) ? null : property;
    }

    /**
     * 特征参数-硬件名称
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByHardware() {
        String hardware = getProperty("ro.hardware");
        if (null == hardware) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = hardware.toLowerCase();
        switch (tempValue) {
            case "ttvm"://天天模拟器
            case "nox"://夜神模拟器
            case "cancro"://网易MUMU模拟器
            case "intel"://逍遥模拟器
            case "vbox":
            case "vbox86"://腾讯手游助手
            case "android_x86"://雷电模拟器
                result = RESULT_EMULATOR;
                break;
            default:
                result = RESULT_UNKNOWN;
                break;
        }
        return new CheckResult(result, hardware);
    }

    /**
     * 特征参数-渠道
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByFlavor() {
        String flavor = getProperty("ro.build.flavor");
        if (null == flavor) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = flavor.toLowerCase();
        if (tempValue.contains("vbox")) result = RESULT_EMULATOR;
        else if (tempValue.contains("sdk_gphone")) result = RESULT_EMULATOR;
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, flavor);
    }

    /**
     * 特征参数-设备型号
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByModel() {
        String model = getProperty("ro.product.model");
        if (null == model) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = model.toLowerCase();
        if (tempValue.contains("google_sdk")) result = RESULT_EMULATOR;
        else if (tempValue.contains("emulator")) result = RESULT_EMULATOR;
        else if (tempValue.contains("android sdk built for x86")) result = RESULT_EMULATOR;
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, model);
    }

    /**
     * 特征参数-硬件制造商
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByManufacturer() {
        String manufacturer = getProperty("ro.product.manufacturer");
        if (null == manufacturer) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = manufacturer.toLowerCase();
        if (tempValue.contains("genymotion")) result = RESULT_EMULATOR;
        else if (tempValue.contains("netease")) result = RESULT_EMULATOR;//网易MUMU模拟器
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, manufacturer);
    }

    /**
     * 特征参数-主板名称
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByBoard() {
        String board = getProperty("ro.product.board");
        if (null == board) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = board.toLowerCase();
        if (tempValue.contains("android")) result = RESULT_EMULATOR;
        else if (tempValue.contains("goldfish")) result = RESULT_EMULATOR;
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, board);
    }

    /**
     * 特征参数-主板平台
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByPlatform() {
        String platform = getProperty("ro.board.platform");
        if (null == platform) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        String tempValue = platform.toLowerCase();
        if (tempValue.contains("android")) result = RESULT_EMULATOR;
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, platform);
    }

    /**
     * 特征参数-基带信息
     *
     * @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机
     */
    private CheckResult checkFeaturesByBaseBand() {
        String baseBandVersion = getProperty("gsm.version.baseband");
        if (null == baseBandVersion) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        int result;
        if (baseBandVersion.contains("1.0.0.0")) result = RESULT_EMULATOR;
        else result = RESULT_UNKNOWN;
        return new CheckResult(result, baseBandVersion);
    }

    /**
     * 获取传感器数量
     */
    private int getSensorNumber(Context context) {
        SensorManager sm = (SensorManager) context.getSystemService(SENSOR_SERVICE);
        return sm.getSensorList(Sensor.TYPE_ALL).size();
    }

    /**
     * 获取已安装第三方应用数量
     */
    private int getUserAppNumber() {
        String userApps = CommandUtil.getSingleInstance().exec("pm list package -3");
        return getUserAppNum(userApps);
    }

    /**
     * 是否支持相机
     */
    private boolean supportCamera(Context context) {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * 是否支持闪光灯
     */
    private boolean supportCameraFlash(Context context) {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    /**
     * 是否支持蓝牙
     */
    private boolean supportBluetooth(Context context) {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
    }

    /**
     * 判断是否存在光传感器来判断是否为模拟器
     * 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。
     *
     * @return false为模拟器
     */
    private boolean hasLightSensor(Context context) {
        SensorManager sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
        Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光线传感器
        if (null == sensor) return false;
        else return true;
    }

    /**
     * 特征参数-进程组信息
     */
    private CheckResult checkFeaturesByCgroup() {
        String filter = CommandUtil.getSingleInstance().exec("cat /proc/self/cgroup");
        if (null == filter) return new CheckResult(RESULT_MAYBE_EMULATOR, null);
        return new CheckResult(RESULT_UNKNOWN, filter);
    }
}

 关键是 readSysProperty这个方法,返回false就不是模拟器是真机,true是模拟器

此包内的四个文件如下:
CheckResult.java
 

package com.lahm.library;

public class CheckResult {
    public static final int RESULT_MAYBE_EMULATOR = 0;//可能是模拟器
    public static final int RESULT_EMULATOR = 1;//模拟器
    public static final int RESULT_UNKNOWN = 2;//可能是真机

    public int result;
    public String value;

    public CheckResult(int result, String value) {
        this.result = result;
        this.value = value;
    }
}
CommandUtil.java

package com.lahm.library;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;

/**
 * Project Name:EasyProtector
 * Package Name:com.lahm.library
 * Created by lahm on 2018/6/8 16:23 .
 */
public class CommandUtil {
    private CommandUtil() {
    }

    private static class SingletonHolder {
        private static final CommandUtil INSTANCE = new CommandUtil();
    }

    public static final CommandUtil getSingleInstance() {
        return SingletonHolder.INSTANCE;
    }

    public String getProperty(String propName) {
        String value = null;
        Object roSecureObj;
        try {
            roSecureObj = Class.forName("android.os.SystemProperties")
                    .getMethod("get", String.class)
                    .invoke(null, propName);
            if (roSecureObj != null) value = (String) roSecureObj;
        } catch (Exception e) {
            value = null;
        } finally {
            return value;
        }
    }

    public String exec(String command) {
        BufferedOutputStream bufferedOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("sh");
            bufferedOutputStream = new BufferedOutputStream(process.getOutputStream());

            bufferedInputStream = new BufferedInputStream(process.getInputStream());
            bufferedOutputStream.write(command.getBytes());
            bufferedOutputStream.write('\n');
            bufferedOutputStream.flush();
            bufferedOutputStream.close();

            process.waitFor();

            String outputStr = getStrFromBufferInputSteam(bufferedInputStream);
            return outputStr;
        } catch (Exception e) {
            return null;
        } finally {
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (process != null) {
                process.destroy();
            }
        }
    }

    private static String getStrFromBufferInputSteam(BufferedInputStream bufferedInputStream) {
        if (null == bufferedInputStream) {
            return "";
        }
        int BUFFER_SIZE = 512;
        byte[] buffer = new byte[BUFFER_SIZE];
        StringBuilder result = new StringBuilder();
        try {
            while (true) {
                int read = bufferedInputStream.read(buffer);
                if (read > 0) {
                    result.append(new String(buffer, 0, read));
                }
                if (read < BUFFER_SIZE) {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}
EmulatorCheckCallback接口

package com.lahm.library;

/**
 * Project Name:EasyProtector
 * Package Name:com.lahm.library
 * Created by lahm on 2018/7/25 15:19 .
 */
public interface EmulatorCheckCallback {
    void findEmulator(String emulatorInfo);
}

在cocos.game.AppActivity这个类里,先声明一个静态变量:
public static boolean isEnumator = false;

在onCreate(Bundle savedInstanceState)方法里这样调用:
this.isEnumator = EmulatorCheckUtil.getSingleInstance().readSysProperty(this, null);
这样就能检测出模拟器还是真机了,为true就是模拟器,false为真机。

再写个方法给typescript层调用:

public static boolean isRunningOnEmulator() {
        return isEnumator;
    }

typescript层这样调用即可:
 

getEmulator() { //检查是否是模拟器
        if(native.reflection) {
            global.bEmulator =  native.reflection.callStaticMethod("com/cocos/game/AppActivity", "isRunningOnEmulator","()Z");
        }
        else
            global.bEmulator = false;
    }

大功告成,实测夜神模拟器,蓝叠模拟器能检测出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国产化系统中遇到的视频花屏、卡顿以及延迟问题的记录与总结

目录 1、国产化系统概述 1.1、国产化操作系统与国产化CPU 1.2、国产化服务器操作系统 1.3、当前国产化系统的主流配置 2、视频解码花屏与卡顿问题 2.1、视频解码花屏 2.2、视频解码卡顿 2.3、关于I帧和P帧的说明 3、国产显卡处理速度慢导致图像卡顿问题 3.1、视频延…

【Git】Git中用到的一些命令

Git文件有四种状态&#xff1a; 未跟踪未修改&#xff08;已跟踪&#xff09;已修改&#xff08;已跟踪&#xff09;已暂存&#xff08;已跟踪&#xff09; 通常我们将项目clone下来就会处于已跟踪状态 1、git diff命令 git diff&#xff1a;查看没有暂存的文件更新哪些部分…

Linux安装Solr-8.9.0

Solr的工作原理可以简单地概括为以下几个步骤&#xff1a; 1. 索引创建&#xff1a;首先&#xff0c;Solr需要创建一个索引&#xff0c;用于存储要搜索的数据。索引是基于Apache Lucene构建的&#xff0c;它将文档拆分为字段&#xff0c;并对字段进行分析和标记化&#xff0c;以…

Nature | 人工智能模型越大就越好吗?

随着生成式人工智能模型&#xff08;AI&#xff09;变得越来越大、越来越强大&#xff0c;一些AI科学家开始提倡更精简、更节能的系统。针对这个趋势&#xff0c;著名科技杂志《Nature》最近发表Anil Ananthaswamy博士的专题文章“人工智能模型总是越大型越好吗&#xff1f;”&…

vue3 + antv/x6 实现拖拽侧边栏节点到画布

前篇&#xff1a;vue3ts使用antv/x6 自定义节点 前篇&#xff1a;vue3antv x6自定义节点样式 1、创建侧边栏 用antd的menu来做侧边栏 npm i --save ant-design-vue4.x//入口文件main.js内 import Antd from ant-design-vue; import App from ./App; import ant-design-vue/…

redis 发布和订阅

目录 一、简介 二、常用命令 三、示例 一、简介 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。下图展示了频道 channel1 &#xff0c;以及订阅这个频道的三个客户…

编程语言学习笔记-架构师和工程师的区别,PHP架构师之路

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

ROS机器人启动move base时代价地图概率性无法加载的原因及解决方法

最近&#xff0c;使用ROS机器人&#xff0c;在启动move_base 节点时&#xff0c;概率性会出现全局和局部代价地图不加载的问题&#xff0c;此时&#xff0c;发布目标点也无法启动路径规划。而且该问题有时候出现概率很低&#xff0c;比如启动10次&#xff0c;会有1次发送该情况…

ASEMI逆变器专用整流桥GBU812参数,GBU812规格

编辑-Z GBU812参数描述&#xff1a; 型号&#xff1a;GBU812 最大峰值反向电压(VRRM)&#xff1a;1200V 平均整流正向电流(IF)&#xff1a;8A 正向浪涌电流(IFSM)&#xff1a;200A 工作接点温度和储存温度(TJ, Tstg)&#xff1a;-55 to 150℃ 最大热阻(RθJC)&#xff1…

node fs模块readFileSync报错SyntaxError: Unexpected token ‘*‘

node fs模块readFileSync报错SyntaxError: Unexpected token * 1.问题再现2.解决方法 1.问题再现 使用node的fs模块readFileSync读取文件时&#xff0c;报错了SyntaxError: Unexpected token 。文件的读取路径是没有问题的。 看到好像是读不了""也。 2.解决方法 …

08 Ubuntu安装docker || 四十五秒极速安装!真的极快,我使用了镜像

因为我是Ubuntu系统的&#xff0c;所以我下面只演示Ubuntu系统。 我使用的是“清华镜像”所提供的步骤&#xff0c;如果你曾多看过我几篇博客&#xff0c;就知道我真的十分喜欢使用清华镜像。 文末附带其他版本安装方式。 1 &#xff08;删除旧版本&#xff09; 如果你以前…

Anaconda详细安装过程

一、前言 Anaconda是一个开源的Python和R编程语言的发行版本&#xff0c;用于数据科学、机器学习、人工智能和科学计算。它提供了一个集成的平台&#xff0c;包含了大量的开源工具、库和软件包&#xff0c;方便用户进行数据分析、处理和建模。 二、实验环境 WIndows10、11 …

leetcode 415.字符串相加

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/add-strings/description/ ps&#xff1a; 从两个字符串的末尾开始遍历&#xff0c;依次相加&#xff0c;若大于等于 10 则使用一个变量记录进位&#xff0c;遍历的时候若两个字符串其中一…

vue3 实现简单瀑布流

一、整理思路 实际场景中&#xff0c;瀑布流一般由 父组件 提供 数据列表&#xff0c;子组件渲染每个图片都是根据容器进行 绝对定位 &#xff0c;从而定好自己的位置取出 屏幕的宽度&#xff0c;设定 图片的宽度 固定 为一个值&#xff0c;计算可以铺 多少列按列数 先铺上第一…

【嵌入式】MKV31F512VLL12 微控制器 (MCU) 、Cyclone® IV E EP4CE10E22I8LN,FPGA-现场可编程门阵列芯片

1、MKV31F512VLL12 微控制器 (MCU) 是适用于BLDC、PMSM和ACIM电机控制应用的高性能解决方案。这些MCU采用运行频率为100MHz/120MHz、带数字信号处理 (DSP) 和浮点单元 (FPU) 的ARM Cortex-M4内核。KV3x MCU配备两个采样率高达1.2MS/s的16位ADC、多个控制定时器以及512KB闪存。 …

【SpringCloud】Stream消息通知使用

文章目录 概述标准MQ 配置POMYML 示例消息发送配置RabbitMQ可视化插件消息消费者 遇到的问题复现解决&#xff1a;修改YML注意 概述 屏蔽底层消息中间件的差异,降低切换成本&#xff0c;统一消息的编程模型 官网&#xff1a; https://spring.io/projects/spring-cloud-stream#…

Docker Dockerfile Docker-compose学习笔记

文章目录 Centos环境下安装Docker配置镜像源 Windows环境下安装Docker配置镜像源 使用Dokcer镜像1.获取镜像2.查看镜像信息(1)列出镜像(2)镜像标签(3)镜像详细信息(4)镜像历史 3.搜索镜像4.删除和清理镜像(1)使用标签删除镜像(2)使用ID删除镜像(3)清理镜像 5.创建镜像(1)基于已…

Git分享-规范/建议/技巧

1. Git多人协作开发流程图 1.1 processOn默认的模板 1.2 改造之后 https://www.processon.com/view/link/64ccaf56a433c931b2f9428a 访问密码&#xff1a;512I ① 总流程图 ② feat分支&#xff08;功能/需求 分支&#xff09;流程 ③ bugfix分支&#xff08;紧急补丁分支&…

微信设置快捷回复话术,快速回复!

微信上如何快速回复&#xff1f;其实是有个小技巧的 微信作为目前最流行的社交媒体平台之一&#xff0c;已经成为许多企业与用户之间沟通的重要渠道。当用户数量的增加和信息交流的频繁&#xff0c;如何提高回复效率就成了某部分人的问题。 微信上是没有快速回复的功能的&#…

315官方点赞!多燕瘦或将成酵素选购唯一标准

食用酵素及其衍生产品&#xff0c;是近年来国内主流电商平台的主要增长类目之一。在全球范围内&#xff0c;酵素的流行由来已久&#xff0c;其中在日本、北美、欧洲等发达国家和地区尤为风靡。据不完全统计&#xff1a;欧洲酵素市场规模约占全球酵素市场份额的40%以上&#xff…