Android问题记录

这篇具有很好参考价值的文章主要介绍了Android问题记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一 Android编程怎样用ICC校准颜色?

在Android编程中,ICC颜色校准通常是通过使用Color Management API进行的。以下是使用ICC校准颜色的步骤:

  1. 首先,确保你的设备支持色彩管理。你可以通过调用ColorManagement.isColorManagementSupported()来检查。

  2. 获取ICC配置文件。你可以从设备的显示器、打印机或其他外设中获取ICC配置文件,或者从网上下载。

  3. 创建ColorSpace对象。使用ColorSpace.getInstance()方法,并传入ICC配置文件作为参数。

  4. 创建一个ColorSpace.Connector对象,它将源色彩空间与目标色彩空间连接起来。你可以使用ColorSpace.connect()方法,并传入源色彩空间和目标色彩空间。

  5. 现在,你可以使用ColorSpace.Connector对象转换颜色值。调用connector.transform()方法,并传入表示颜色的float数组。

  6. 最后,将转换后的颜色值应用到你的应用程序中,例如,通过调用Canvas.drawColor()或者设置视图的背景色。

注意,这些API可能需要Android API 26(Android 8.0 Oreo)或更高版本。此外,进行颜色校准可能会涉及复杂的色彩理论和实践,因此在进行开发之前,最好对这些知识有一定的了解。

二 Android编程 用ICC校准颜色代码

在Android编程中,要使用ICC校准颜色,你需要先确保设备支持高级色彩管理。以下是一段示例代码,展示了如何使用ICC校准颜色:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // 检查设备是否支持色彩管理
    if (ColorManagement.isColorManagementSupported()) {
        try {
            // 从ICC配置文件创建ColorSpace
            InputStream inputStream = new FileInputStream("path_to_your_icc_profile.icc");
            ColorSpace iccColorSpace = ColorSpace.getInstance(inputStream);

            // 获取默认的sRGB色彩空间作为源色彩空间
            ColorSpace sRGB = ColorSpace.get(ColorSpace.Named.SRGB);

            // 创建连接器,用于在两个色彩空间之间转换
            ColorSpace.Connector connector = ColorSpace.connect(sRGB, iccColorSpace);

            // 定义sRGB颜色值
            float[] sRgbColor = {1.0f, 0.0f, 0.0f}; // 红色

            // 使用连接器将颜色从sRGB空间转换到ICC色彩空间
            float[] iccColor = connector.transform(sRgbColor);

            // 在这里使用转换后的iccColor值
            // 例如,设置视图的背景色或绘制到Canvas上
            // 注意:此处的颜色值是线性的,可能需要转换为0-255范围的整数

        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
        }
    } else {
        // 设备不支持色彩管理
        Log.e("ColorCalibration", "Color management is not supported on this device.");
    }
} else {
    // Android版本低于8.0 (API 26),不支持Color Management API
    Log.e("ColorCalibration", "Color management requires at least Android Oreo (API 26).");
}

请注意,上面的代码需要在Android Oreo(API 26)或更高版本上运行,并且你需要有一个ICC配置文件的路径。此外,处理颜色校准时,你可能需要对颜色值进行额外的转换,例如将线性颜色空间的值转换为适合显示的0-255范围。

此外,如果你的应用目标是更广泛的Android设备兼容性,可能需要考虑一种降级方案,因为Color Management API在Android O之前的版本中不可用。

三 C语言和汇编之间的关系

C语言和汇编语言之间有着密切的关系,它们可以相互调用和混合使用。以下是它们之间的关系:

  1. C语言是一种高级语言,它提供了丰富的语法和功能,使程序员能够更轻松地编写复杂的程序。C语言的代码通常更易于理解和维护。

  2. 汇编语言是一种低级语言,它提供了对计算机硬件和指令集的直接访问。汇编语言的代码更接近计算机底层的操作,因此更高效,但也更难以理解和编写。

  3. C语言可以直接调用汇编语言的函数,这使得程序员可以利用汇编语言的高效性能来优化特定的代码段。

  4. 汇编语言可以调用C语言的函数,这使得程序员可以利用C语言丰富的库函数和功能来简化汇编语言程序的开发。

  5. 在一些特定的应用场景中,程序员可以通过内联汇编的方式在C语言代码中直接嵌入汇编代码,以实现对特定指令的精细控制和优化。

总的来说,C语言和汇编语言之间的关系是相辅相成的。C语言提供了高级的抽象和易用性,而汇编语言提供了对底层硬件的直接控制和高效性能,程序员可以根据实际需求选择合适的语言来编写程序。

四 ubuntu 安装汇编运行环境

要在Ubuntu上安装汇编运行环境,您可以按照以下步骤进行操作:

1,打开终端,并使用以下命令更新软件包列表:

sudo apt update

2,安装汇编语言编译器(如NASM)和调试器(如GDB):

sudo apt install nasm gdb

3,检查是否安装成功:

nasm -v gdb --version

4,创建一个简单的汇编程序文件(比如hello.asm),并使用nasm编译它:

nasm -f elf64 -o hello.o hello.asm

5,使用gcc链接器将编译后的目标文件链接成可执行文件:

gcc -o hello hello.o

6,运行生成的可执行文件:

./hello

现在您已经在Ubuntu上成功安装了汇编运行环境,并且可以编写和运行汇编程序了。希望这些步骤能够帮助您顺利进行汇编开发工作。

五 已知4点坐标 判断任意坐标是否在旋转后的长方形内?

要判断一个点是否在旋转后的长方形内,你需要知道长方形的四个顶点坐标。以下是一个算法描述:

设长方形的四个顶点坐标分别为A(x1,y1), B(x2,y2), C(x3,y3), D(x4,y4),任意点P(x,y)。

  1. 计算向量AB、BC、CD和DA: AB = B - A BC = C - B CD = D - C DA = A - D

  2. 计算向量AP、BP、CP和DP: AP = P - A BP = P - B CP = P - C DP = P - D

  3. 利用向量叉乘(cross product)判断P点是否在每条边的同侧: AB × AP、BC × BP、CD × CP、DA × DP

叉乘结果的符号表明了点P相对于边的位置:

  • 如果AB × AP >= 0,那么点P在边AB的同侧或边上。
  • 如果BC × BP >= 0,那么点P在边BC的同侧或边上。
  • 如果CD × CP >= 0,那么点P在边CD的同侧或边上。
  • 如果DA × DP >= 0,那么点P在边DA的同侧或边上。
  1. 如果以上四个叉乘结果都不小于0,说明点P在长方形的每一条边的内侧或边上,即点P在长方形内或边界上;否则,点P在长方形外。

在二维空间中,两个向量u(x1,y1)和v(x2,y2)的叉乘可以定义为: u × v = x1y2 - x2y1

这将给出一个标量值,其符号表示点P相对于边的位置。

这里是一个简化版的伪代码示例:

function isPointInsideRotatedRectangle(A, B, C, D, P):
    AB = B - A
    BC = C - B
    CD = D - C
    DA = A - D

    AP = P - A
    BP = P - B
    CP = P - C
    DP = P - D

    cross1 = crossProduct(AB, AP)
    cross2 = crossProduct(BC, BP)
    cross3 = crossProduct(CD, CP)
    cross4 = crossProduct(DA, DP)

    if cross1 >= 0 and cross2 >= 0 and cross3 >= 0 and cross4 >= 0:
        return true
    else:
        return false

function crossProduct(u, v):
    return u.x * v.y - u.y * v.x

请注意,这个算法假设长方形顶点是按顺时针或逆时针顺序排列的。如果顶点的顺序未知或不一致,你需要首先将它们排序为一致的顺序。此外,如果叉乘结果等于0,则表示点位于边上。

六 jave的class文件生成的机器码和c,c++编译生成的机器码一样吗? 

不完全相同。当Java程序被编译后生成的.class文件包含的是Java字节码,而当C和C++程序被编译后生成的机器码是针对特定的硬件架构的。 Java字节码是一种中间代码,它需要在Java虚拟机(JVM)上解释执行,而C和C++编译生成的机器码是直接可执行的二进制代码。

另外,C和C++编译生成的机器码是直接面向硬件的,而Java字节码是面向Java虚拟机的。这意味着Java程序的执行依赖于Java虚拟机的解释和执行,而C和C++程序的机器码是直接在硬件上执行的。

因此,虽然最终都是机器码,但Java字节码和C、C++程序编译生成的机器码之间存在较大的区别。

七 CPU架构有哪些?

目前常见的CPU架构主要有以下几种:

  1. x86架构:由英特尔和AMD等公司开发的,广泛应用于个人电脑和服务器领域。
  2. ARM架构:由ARM公司开发的,主要用于移动设备、嵌入式系统和物联网设备。
  3. Power架构:由IBM公司开发的,主要用于高性能计算和企业级服务器领域。
  4. MIPS架构:由MIPS Technologies公司开发的,主要用于嵌入式系统和网络设备。
  5. SPARC架构:由甲骨文公司开发的,主要用于企业级服务器领域。

八 编译C/C++库为so

要将C/C++库编译为so(共享对象)文件,可以按照以下步骤进行操作:

  1. 创建一个包含库源代码的文件夹,并在其中创建一个名为“CMakeLists.txt”的文件,用于指定编译选项和链接库的信息。

  2. 在CMakeLists.txt文件中添加以下内容

    cmake_minimum_required(VERSION 3.5)
    project(mylibrary)
    
    set(CMAKE_CXX_STANDARD 11)
    
    add_library(mylibrary SHARED
        source_file1.cpp
        source_file2.cpp
        # 添加所有库源文件
    )
    
  3. 在库源代码文件夹中创建一个名为“build”的文件夹,并在其中打开终端。

  4. 在终端中运行以下命令,用CMake来生成Makefile:

    cmake ..
  5. 接着,在终端中运行以下命令,用Make来编译库文件:
    make
  6. 编译完成后,在“build”文件夹中会生成一个名为“libmylibrary.so”的共享对象文件,即为编译完成的库文件。

以上就是将C/C++库编译为so文件的基本步骤,可以根据实际情况进行调整和优化。

九 linux 中 Chmod 777是什么意思

9.1 Linunx中chmod 777介绍:

  • 在Linux中,chmod 777是一种权限设置命令
  • 它表示将文件或目录的权限设置为所有用户都具有读取、写入和执行的权限

9.2 Linunx中的用户分类

在Linux中,对文件和目录的访问对每个人来说都是不可用的。它们是根据所有权和属性来划分的。有三个不同类别的用户可以访问文件系统,他们如下:

  • Owner:是指创建文件/目录的文件所有者
  • Group:是指一组成员
  • Others:是指可以访问系统的其他所有人

9.3 Linunx中的文件类型权限

在Linux中,每一个用户都有一套不同的权限属性,同样有三种类型的权限:

  • 读取 (r) – 用户只能读取或查看文件/目录。他们不能对文件做任何修改。
  • 写入 (w) – 用户可以修改文件或目录。你可以删除、移动、重命名或对文件或目录做任何修改。
  • 执行 (x) – 用户可以运行脚本或使文件可执行。

9.4 Linux中的文件权限:数值系统

在Linux系统中,读、写和执行的权限是以下列方式表示的,这些权限的数值是由它们的二进制8位数据得出的。

基于上述数字系统,不同的权限集可以有很多组合,其中大多数使用三位数系统,代表权限数字的总和

0 (0+0+0) 无权限 ---
1 (0+0+1) 仅执行 --x
2 (0+2+0) 仅写入 -w-
3 (0+2+1) 读取和执行 -wx
4 (4+0+0) 仅读取 r--
5 (4+0+1) 读取和执行 r-x
6 (4+2+0) 读取和写入 rw-
7 (4+2+1) 读取,写入和执行 rwx

9.5 Chmod 777权限:

  • Chmod本质上意味着 “改变文件或目录的模式”,当执行777时,第一个数字指的是所有者的权限;第二个数字是指组的权限;第三个数字表示其他用户的权限值。
  • 基本上只要使用这个命令,系统中的任何人都可以查看、修改、删除、执行或对该文件或目录做任何事情。所以chmod 777 命令被认为是非常敏感的,可能会带来安全风险。
  • 所以建议用替代方案,更安全的 chmod 644 命令来设置文件权限,644的权限号将只授予所有者读写“6”的权限,读“4”的权限会分配给所有组员和其他用户。

9.6 chmod 777命令使用

chmod 777 <filepath or filename> 

例如:

chmod 777 test.txt

同样 chmod 644一样用法,也可以用以下命令检查一个文件/目录的数字权限值

stat -c "%a" <filepath or filename>
例如:

stat -c "%a" test.txt

十 CMake 编译C文件为android用的64位动态库

 要将C文件编译为 Android 64 位动态库,您可以使用 CMake 和 Android NDK。以下是一个简单的示例 CMakeLists.txt 文件,用于将 C 文件编译为 Android 64 位动态库:

cmake_minimum_required(VERSION 3.5)

# 设置交叉编译工具链
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21) # Android API 版本
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) # 选择 64 位架构
set(CMAKE_ANDROID_NDK /path/to/your/ndk) # 设置 Android NDK 路径

# 设置编译器和工具链
set(CMAKE_C_COMPILER ${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang)
set(CMAKE_CXX_COMPILER ${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++)

# 设置编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") # 添加 -fPIC 选项
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib") # 添加链接选项

# 创建动态库
add_library(mylibrary SHARED mysource.c)

请将 /path/to/your/ndk 替换为您的 Android NDK 路径,并将 mysource.c 替换为您的实际源文件。然后在终端中运行以下命令来生成 Android 64 位动态库:

mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/CMakeLists.txt ..
make

这将在 build 目录中生成您的 Android 64 位动态库。

十一 Cmake add_library 生成的动态库是64位还是32位的?

 CMake add_library生成的动态库取决于你的操作系统和CMake配置。通常情况下,CMake会根据操作系统的位数自动选择生成64位或32位的动态库。如果你需要明确指定生成的位数,可以在CMakeLists.txt文件中使用CMAKE_LIBRARY_ARCHITECTURE来指定目标平台的位数。

十二 Android 根据型号获取系列名字

在 Android 中,可以通过使用 Build 类来获取设备的型号信息。然后,我们需要将这些型号与已知的手机品牌进行对比,从而确定所属的系列名称。

下面是一段示例代码,展示了如何根据设备型号获取系列名称:

import android.os.Build;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        String model = Build.MODEL; // 获取设备型号
        
        if (model != null && !model.isEmpty()) {
            String brandName = getBrandFromModel(model); // 调用函数获取品牌名称
            
            Log.d("Device", "Series Name: " + brandName);
        } else {
            Log.e("Device", "Failed to retrieve device model");
        }
    }
    
    private String getBrandFromModel(String model) {
        switch (model) {
            case "SM-G900F": return "Samsung Galaxy S6";
            case "Nexus 5X": return "Google Nexus 5X";
            case "iPhone X": return "Apple iPhone X";
            default: return "";
        }
    }
}

上述代码中,我们首先通过 Build.MODEL 获取到设备的型号,并传递给 getBrandFromModel() 函数。该函数会返回相应的品牌名称。

注意:由于不同的设备有不同的型号命名规则,因此需要自行添加更多的条件判断语句或者使用正则表达式等技术来处理特殊情况。

十三 NFC在高版本手机上获取TAG失败问题

NFC低版本可以正常获取TAG,但在android12以上会获取失败,原因是Adnroid12以后PendingIntent的新特性导致。

之前使用的PendingIntent.FLAG_IMMUTABLE,此标志创建的PendingIntent是不可变的。

安卓12使用PendingIntentFLAG_MUTABLE,是可变的,替换下即可

private NfcAdapter mNfcAdapter;
private PendingIntent mPendingIntent;   
    
private void initNfc() {
   mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
   mPendingIntent = PendingIntent.getActivity(activity, 0,
   new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 
   PendingIntent.FLAG_MUTABLE);
}

private void nfcEnabled() {
  if (mNfcAdapter != null && mNfcAdapter.isEnabled()) {
     mNfcAdapter.enableForegroundDispatch(activity, mPendingIntent, intentFilters, techLists);
   }
}

十四 pe文件结构和elf文件结构区别

PE文件结构和ELF文件结构是两种不同的可执行文件格式,通常用于Windows和Linux操作系统上的程序。它们之间的主要区别在于它们的文件结构和标识符。

PE文件结构:

  1. PE文件结构是用于Windows操作系统的可执行文件格式。
  2. PE文件结构包括DOS头、文件头、可选头、节表和数据段等部分。
  3. PE文件使用COFF格式的目标文件,并在其基础上添加了Windows特定的头部和节表。
  4. PE文件使用PE标识符作为文件的标识符。

ELF文件结构:

  1. ELF文件结构是用于Unix-like操作系统的可执行文件格式,如Linux。
  2. ELF文件结构包括ELF头、节头表、节数据和符号表等部分。
  3. ELF文件使用ELF格式的目标文件,其中包括了程序头表和节头表。
  4. ELF文件使用ELF标识符作为文件的标识符。

总的来说,PE文件结构和ELF文件结构是针对不同操作系统的可执行文件格式,它们具有不同的文件结构和标识符。因此,在不同的操作系统上运行的程序通常需要使用相应的可执行文件格式。

十五 GNU包含哪些工具

GNU项目包含了大量的工具和软件,其中一些主要的工具和组件包括:

  1. GNU编译器集合(GCC):用于编译C、C++、Fortran等程序的编译器集合。
  2. GNU工具链(GNU Toolchain):包括GNU编译器集合、GNU调试器(GDB)和其他工具,用于开发和调试软件。
  3. GNU核心实用程序(Core Utilities):包括一系列基本的命令行工具,如ls、cp、rm等,用于文件操作和系统管理。
  4. GNU Bash:GNU的默认shell,提供了一个强大的命令行界面和脚本编程语言。
  5. GNU Emacs:一个功能强大的文本编辑器,也被称为“操作系统内核的扩展”。
  6. GNU Make:一个用于自动化软件构建过程的工具,通常用于编译和链接程序。
  7. GNU Bison:一个用于生成语法分析器的工具,通常用于编译器和解释器的开发。
  8. GNU GDB:一个功能强大的调试器,用于调试C、C++等程序。

除此之外,GNU项目还包含了许多其他工具和组件,涵盖了操作系统、开发工具、实用程序等多个领域。文章来源地址https://www.toymoban.com/news/detail-809411.html

到了这里,关于Android问题记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 日常问题记录-Android-Bug-OOM

    大家好哇,我是梦辛工作室的灵,最近的项目中,我又遇到了一个bug,就是我写了一个类 将app会用到的Bitmap缓存起来进行管理,防止OOM嘛,不过莫名奇妙的事情还是发生了,内存依旧上涨,且没有释放 然后我就查到了获取缓存对象的那里的代码,打上了日志数据,然后就发

    2024年02月15日
    浏览(86)
  • 记录解决Android Studio下载gradle超时问题

    大三学生,2023年3月19号晚,首次下载Android Studio2022版本并新建项目,发现在下载gradle总是连接超时,舍友则没有这个问题,用的是同一个安装包。 查阅文献太多,忘记都有哪些了,就不列出来了,都是公开的。 总结:连接不上外网的谷歌导致网络超时,通过其他方法下载好

    2024年02月05日
    浏览(100)
  • Android 调用TTS语音引擎过程及问题记录

      背景是需要在华为平板上部署一个能够进行相关中文语音提示的APP,华为系统为鸿蒙3.0,对应Android API 12.   调用TTS引擎之前,首先要确认自己的设备中是否安装了相关的文本转语音引擎以及是否支持中文,查看方法为“设置-辅助功能-无障碍-文本转语音”,鸿蒙系统是

    2024年02月16日
    浏览(41)
  • 【Android Gradle 插件】更新依赖方式,同时解决github三方库引用无法使用问题

    目录 首先看一下完整的 settings.gradle 依赖介绍 1、Maven 远程仓库配置 2、目录配置 3、完整代码示例 二、根目录下 build.gradle 构建脚本分析 pluginManagement 脚本块 , 用于 配置 Gradle 插件的 Maven 仓库 , 配置的是 构建过程 中 , 使用的仓库 ; dependencyResolutionManagement 脚本块 , 用于 配置

    2024年02月16日
    浏览(40)
  • 从零开始学数据结构和算法:腾讯Android开发面试记录,已开源_android 开发面试算法

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新Android移动开发全套学习资

    2024年04月25日
    浏览(57)
  • 【问题记录】fatal: unable to access ‘https://github.com/‘: Recv failure: Connection was reset

    GitHub上的项目克隆到本地 一般是这是因为服务器的SSL证书没有经过第三方机构的签署,所以才报错 在 GitBash 中执行以下命令

    2024年02月15日
    浏览(69)
  • Android Studio Hedgehog 代码补全失效问题记录

    Android Studio Hedgehog 代码补全失效问题记录 代码失效问题网上答案很多,如: 关闭省电模式;清空缓存;重启电脑;删除重新安装啥的。但是很一行都没有用,并且我电脑上的4.3.3版本的Android Studio是没有该问题的。 所以我推断应该是我的Hedgehog版本设置的问题 但是昨天还好好

    2024年02月22日
    浏览(48)
  • Flutter & Android问题记录 - 升级Android Studio 2022.2.1版本后运行项目报错

    最近一个Flutter项目有新需求,开发时一直是在iOS设备上运行,花了几天做完后运行到Android设备测试,结果项目构建失败了。 Flutter: 3.7.11 Android Studio: 2022.2.1 Java: 17.0.6 Gradle: 7.4 Android Gradle Plugin (AGP): 4.1.3 项目构建报错日志: 报错有点眼熟,根据以往开发经验,应该是Gradle版本

    2023年04月24日
    浏览(96)
  • 【R语言】完美解决devtools安装GitHub包失败的问题(以gwasglue为例)

    Rstudio,R4.3.1,命令在Rstudio的命令行即console中运行。 使用devtools安装一个github的包。 devtools: devtools 是 R 语言中一个非常有用的包,它提供了一套工具和函数,用于开发、测试和维护 R 包, devtools 可以帮助 R 包的开发人员更轻松地进行包的创建、文档编写、测试和发布等任

    2024年02月08日
    浏览(61)
  • android计算器界面布局线性布局跨2行,使用Kotlin高效地开发Android App(一,GitHub标星3.2K

    get(url).placeholder(R.drawable.shape_default_round_bg) .error(R.drawable.shape_default_round_bg) // .apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(DisplayUtil.dp2px(context, 6f), 0))) .transform(RoundedCornersTransformation(DisplayUtil.dp2px(context, 6f), 0)) .into(this) } /** 占位符圆形 */ fun ImageView.loadCircle(url: Drawable) {

    2024年04月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包