目录
android gradle的日常使用

1.修改Gradle文件的存放位置

默认情况下,android studio中gradle存放本地 C:\Users\用户名.gradle 文件夹下,下面存放着不同版本的gradle文件,如果想要修改存放位置可以在File>setting>Build,Execution,Deployment>Build Tools>gradle下
图片描述

2.gradle的兼容问题

图片描述
说完gradle文件存放的位置,不得不说一下下面这张图中的文件,这个文件夹包含了一个wrapper文件夹,那么为什么要有这个呢?gradle是一门发展很快的语言,语言发展快,api也就会经常更新,构建语言含有丰富的插件,变化很快的话,就难以兼容以前老的版本。而wrapper就用来解决解决兼容性问题。wrapper里定义了gradle的版本。

groovy
复制代码
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

我现在这个项目用的gradle版本是6.8,构建这个工程时,它都会用我所绑定的gradle版本(避免版本兼容性问题)所以wrapper的作用就是会来检查在你构建这个工程的机器上有没有6.8这个版本。如果有就开始构建,没有就去下载这个版本。再举个例子,假如你现在从网上下载了一个项目,而这个项目它所绑定的gradle版本是6.8的,而你的机器现在只有6.8版本的gradle,那么当这个项目在你这台机器上构建的时候,wrapper就会看你机器上有没有6.8版本的gradle,发现没有的话就会去到所提供的url下载这个版本。
这个文件夹最主要的作用就是,当你clone了别人的项目,你网络又不好时,可以修改gradle的版本,使用本地已经下载好的gradle,让项目顺利构建。同时也可以避免本地下载一堆的gradle,占用磁盘空间。
写这篇文章才发现,我已经下载了那么多
图片描述

3.Android gradle plugin(gradle插件简称AGP) 和gradle的关系对照

图片描述
您可以在 Android Studio 的 File > Project Structure > Project 菜单中指定 Gradle 版本,也可以使用命令行更新 Gradle 版本。官网链接

4.常用的gradle命令

4.1 编译并生成相应的apk文件

java
复制代码
./gradlew clean 清除/app目录下的build文件夹
./gradlew build //依赖并编译打包
./gradlew assembledebug  //打debug包
./gradlew assemblerelease //编译并打release的包
./gradlew installrelease //release模式打包并安装
./gradlew uninstallrelease //卸载release模式包
./gradlew build --refresh-dependencies  //刷新项目依赖
//编译并打印日志
./gradlew build --info
//译并输出性能报告,性能报告一般在 构建工程根目录 build/reports/profile
./gradlew build --profile
// 调试模式构建并打印堆栈日志
./gradlew build --info --debug --stacktrace
// 强制更新最新依赖,清除构建并重新构建
./gradlew clean build --refresh-dependencies

4.2.任务查询命令

java
复制代码
//查看任务
./gradlew tasks 
//查看所有任务,包括缓存任务 
.gradlew tasks -all

//针对某个module [modulename]的某个TaskName运行
.gradlew :modulename:taskName

说明,module 定义在 工程根 settings.gradle 下,由 include 指定
子模块任务,不代表工程根也有同样的任务,所以需要单独查询moduel 最佳命名实践为 全小写英文 防止编译兼容问题。

4.3 查看包依赖

java
复制代码
./gradlew dependencies

//查看模组的依赖
./gradlew app:dependencies
//检索依赖库
.gradlew app:dependencies |grep CompileClasspath
//windows 环境下
.gradlew app:dependencies | findstr "CompileClasspath"
// 将检索到的依赖分组找到 比如 multiDebugCompileClasspath 就是 multi 渠道分发的开发编译依赖
./gradlew app:dependencies --configuration multiDebugCompileClasspath
// 一般编译时的依赖库,不是固定配置方式,建议检索后尝试
./gradlew app:dependencies --configuration compile
// 一般运行时的依赖库,不是固定配置方式,建议检索后尝试
./gradlew app:dependencies --configuration runtime

4.4 统计task时长

gradle构建项目是将项目分成一个个的task的构建,通常为了分析哪个task花费了较长时间,需要我们自己写一些类来得到不同task的时长,好做针对性优化,这里有篇博客写的比较好,敢兴趣的直接跳转。统计task时长

4.5 有用的小技巧

有用的技巧

  1. resolutionStrategy 统一全局第三方库版本
  2. 修改包的输出路径
  3. 找到版本冲突的库
  4. 修改依赖方式

5.gradle.properties 文件

plaintext
复制代码
AS项目的根目录下有一个gradle.properties文件,专门用来配置全局键值对数据的。可用于存放敏感数据。

将它从git版本控制中排除,这样gradle.properties文件只能保留在本地,从而不用担心keystore文件等敏感信息泄漏。常见的配置如下

java
复制代码
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel = true
# 为 Studio 分配默认的内存大小
org.gradle.jvmargs=-Xmx2048m
# 表示使用 AndroidX
android.useAndroidX=true
# 表示将第三方库迁移到 AndroidX
android.enableJetifier=true
# 如果不设置为 false ,在某些机型上将不被允许安装
android.injected.testOnly=false

同时配合BuildConfig可以定义一些常量,如果你的app有两以上不同的环境运行,那么可以尝试一下这种方式定义baseUrl

  1. 第一步:在app/build.gradle设置BuildConfig
java
复制代码
android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //buildConfigField用于给BuildConfig文件添加一个字段,baseUrl为键,后面的${releaseUrl}为值
            buildConfigField("String","baseUrl","\"${releaseUrl}\"")
        }
        debug{
            buildConfigField("String","baseUrl","\"${debugUrl}\"")
        }
    }
    ...
}
  1. 第二步:取值定义在gradle.properties文件中。
java
复制代码
debugUrl = https://xxxdebug.com
realeaseUrl= https://xxxrelease.com
  1. 使用(你可以在项目中任意位置以BuildConfig.key的形式调用在buildConfigField上面定义的常量)
java
复制代码
Log.d("tag",BuildConfig.baseUrl)

在debug环境下打印结果为https://xxxdebug.com
在release环境下打印结果为https://xxxrelease.com
这样就可以实现在不同包中使用不同的baseUrl.

6.使用Gradle规定组件之间资源前缀

通常我们的项目不是单个模块,分成了多个模块,因为我们拆分出了很多业务组件和功能组件,在把这些组件合并到**“app壳工程”时候就有可能会出现资源名冲突问题,例如A组件和B组件都有一张叫做“ic_back”的图标**,这时候在集成模式下打包APP就会编译出错,解决这个问题最简单的办法就是在项目中约定资源文件命名规约,比如强制使每个资源文件的名称以组件名开始,这个可以根据实际情况和开发人员制定规则。当然了万能的Gradle构建工具也提供了解决方法,通过在在组件的build.gradle中添加如下的代码:

java
复制代码
 //设置了resourcePrefix值后,所有的资源名必须以指定的字符串做前缀,否则会报错。
//但是resourcePrefix这个值只能限定xml里面的资源,并不能限定图片资源,所有图片资源仍然需要手动去修改资源名。
resourcePrefix "girls_"

7.gradle警告配置

java
复制代码
   // 代码警告配置
    lintOptions {
        // 禁用文本硬编码警告
        disable 'HardcodedText'
        // 禁用图片描述警告
        disable 'ContentDescription'
    }

8.build.gralde(project)

8.1旧版本

旧版本的build.gradle文件是这样的

java
复制代码
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.5.10'
    ext.navigationVersion = '2.3.1'
    //注释1:
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven { url 'https://jitpack.io' }
        maven { url "https://maven.aliyun.com/repository/public" }
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.2"
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31'

        classpath "com.tencent.bugly:tinker-support:1.2.3"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

 //注释2:
allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven { url "https://www.jitpack.io" }
        maven { url 'https://jitpack.io' }
        maven { url "https://maven.aliyun.com/repository/public" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
  • 注释1中buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven仓库地址等。
  • 而注释2在build.gradle文件中直接声明的依赖项、仓库地址等信息是项目自身需要的资源。

8.2 新版本build.gradle(project)

java
复制代码
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

上面使用了DSL写法,语法为

java
复制代码
plugins {
    id «plugin id»                                            // (1)
    id «plugin id» version «plugin version» [apply «false»]   // (2)
}

plugin id 和 plugin version 是必需的 且必须是常量,字面量,字符串.其他语句都是不允许的

apply 是可选的,默认是 true;它是控制在应用插件的时候是否立刻使用插件的默认行为。

这个 plugins{} 块 是不能嵌套在别的配置块里的,必须是脚本的顶级模块。

8.3 应用插件到不同的模块(module)

应用插件到子项目
可以利用 plugins {} 的 apply 选项将插件应用到某些项目而不是所有项目里。
默认 plugins {} 的插件是立即被解析并应用的。
可以使用 apply false 告诉 Gradle 不应用到当前项目,
然后在子项目的脚本中使用 apply plugin <> 或者 plugins{} 应用插件
settings.gradle中

plaintext
复制代码
include 'helloA'
include 'helloB'
include 'goodbyeC'

导入了3个模块
然后在build.gradle中

java
复制代码
plugins {
    id 'org.gradle.sample.hello' version '1.0.0' apply false
    id 'org.gradle.sample.goodbye' version '1.0.0' apply false
}



subprojects {
    if (name.startsWith('hello')) {
        apply plugin: 'org.gradle.sample.hello'
    }
}

goodbyeC/build.gradle

java
复制代码
plugins {
    id 'org.gradle.sample.goodbye'
}

上面的示例演示了如何给多个子项目分别应用不同的插件。

8.4 setting.gradle(旧版)

java
复制代码
include ':app'
rootProject.name = "CustomView"

8.5setting.gralde(新版)

和旧版仅仅是管理项目和不同模块之间的关系不同,新的setting.gradle还添加了
这个 pluginManagement DSL 是用来管理插件的,它可以配置插件,自定义仓库,自定义解析规则等。
pluginManagement{} 只能定义在两个地方:settings.gradle 里,并且必须是第一个模块

java
复制代码
//插件管理
pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
//管理第3方依赖
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "CustomView"
include ':app'

另一个是init.gradle 里

java
复制代码
settingsEvaluated { settings ->
    settings.pluginManagement {
        plugins {
        }
        resolutionStrategy {
        }
        repositories {
        }
    }
}

9 使用ext进行统一版本配置

java
复制代码
ext {
    android = [
            compileSdkVersion   : 29,
            buildToolsVersion   : "30.0.2",
            applicationId       : "com.xionggouba.bearseller",
            minSdkVersion       : 19,
            targetSdkVersion    : 30,
            versionCode         : 27,
            versionName         : "3.9.1",
            defaultPublishConfig: 'release',
            publishNonDefault   : true,
            multiDexEnabled     : true,
            mapKey              : 'c7e1ee468aa1bf8a6739',
            pushKey             : '65aae199a0059eb1dbe7',
            pushChannel         : 'developer-default',
    ]
    appid = [
            app           : "com.xionggouba.bearseller",
            login         : "com.huitao.login",
            home          : "com.huitao.home",
            webview       : "com.huitao.webview",
            main          : "com.huitao.main",
            productManager: "com.huitao.productmanager",
            personal      : "com.huitao.personalcenter",
            map           : "com.huitao.map",
            bluetooth     : "com.huitao.bluetooth",
            push          : "com.huitao.push",
            markketing    : "con.huitao.marketing",
            printer       : "com.huitao.printer"
    ]
    versions = [
            "lifecycle_version": "2.2.0",
            "arch_version"     : "2.1.0",
            "retrofit_version" : "2.6.2",
            "dialog_version"   : "3.3.0",
            "glide_version"    : "4.9.0",
            "hilt"             : "2.28-alpha",
            "kotlin_version"   : "1.4.10",
            "fragment_version" : "1.2.5",
            "room_version"     : "2.2.6"
    ]
]

通常为了方便版本管理,我们会在根目录下创建一个config.gradle文件,统一管理版本号,然后在build.gradle(project)下使用

java
复制代码
apply  from "config.gradle"

引入,然后使用,比如依赖room库

java
复制代码
 implementation "androidx.room:room-runtime:$versions.room_version"

10 build.gradle(app)

java
复制代码
//该模块为应用程序模块,可以直接运行
apply plugin: 'com.android.application'

android {
     //指定项目的编译版本,
     compileSdkVersion 31
     //指定项目构建工具的版本
     buildToolsVersion "30.0.3"
     defaultConfig {
		 //项目包名为com.example.test
	 	 applicationId "com.example.test"
	 	 //最低兼容到Android 5.0版本
	 	 minSdkVersion 21
		 //指定已做过充分测试的目标版本
 		 targetSdkVersion 25
         //版本号,这个是给开发者看的,以后应用升级都是以这个为准,范围大于1的整数
	 	 versionCode 1
         // 这个是版本名称,给用户看的,
		 versionName "1.0"
	 	 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         
            // 仅保留中文语种的资源
        resConfigs 'zh,zh-rCN'

        // 仅保留 xxhdpi 图片资源(目前主流分辨率 1920 * 1080)
        resConfigs 'xxhdpi'
         
         ndk {
            // 设置支持的SO库架构,目前上支持armeabi-v7a ,和arm64-v8a就可以运行在大部分手机上了
		   // abiFilters 'arm64-v8a', 'x86_64','armeabi' ,
            abiFilters   'arm64-v8a','armeabi-v7a' // ,'armeabi-v7a' //'x86_64', ,
        	}
 	 }
    
    //配置签名
    /**
     *  Linux或者Mac
     *  gradle assembleRelease  生成release版本
     *  gradle assembleDebug
     *
     * win
     *  gradlew assembleRelease  生成release版本
     *  gradlew assembleDebug
     *
     */
    signingConfigs {
        release {
            keyAlias 'android'  //随便起
            keyPassword ''   //生成签名是的密码
            storeFile file('../mobile-app.jks')  //签名文件
            storePassword 'adsda2++' //你自己的密码
            v1SigningEnabled true   //v1 签名
            v2SigningEnabled true   //v2 签名
        }
        debug {
            keyAlias 'ttyh.android.key'
            keyPassword 'adsda2++' //你自己的密码
            storeFile file('../mobile-app.jks')
            storePassword 'ttyh-123456++'
            v1SigningEnabled true   
            v2SigningEnabled true
        }
    }
      
    
    //打包偏好设置
 	 buildTypes {
	 	 //指定生成正式版安装文件的配置
 		 release {
             //代码不进行混淆
             minifyEnabled false
             //压缩文件
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources false
             //指定混淆的规则文件,proguard-android.txt为默认的混淆文件,定义了一些通用的混淆规则;
             //proguard-rules.pro文件位于当前项目的根目录下,定义一些项目特有的混淆规则。
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  	 	}
         
         //指定测试版的安装文件配置
         debug {
            minifyEnabled false
            signingConfig  signingConfigs.debug
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-		rules.pro'
        }
  	}
    
    
        productFlavors{
        urlDebug{
            signingConfig signingConfigs.debug    //引用前面的签名配置
            //测试环境Url,指定不同环境下的域名,到时可以通过BuildConfig.SERVER_URL 获取到域名
             buildConfigField 'String',"SERVER_URL", '\"https://xxx.com'
        }
        urlRelease{
            signingConfig signingConfigs.release
            //生产环境Url
            buildConfigField 'String', 'SERVER_URL','\"https://xxx.com'
        }
    }
    
    
    
       //不同资源文件尺寸的偏好
    flavorDimensions 'default'  

    
    //kotlin 1.1.4开始,新增3个特性,要开启这3个特性,需要下面的设置
    //1.任何类中view 属性都会被缓存为ViewHolder;
    //2.提供@Parcelize 可以让任何类以一种简单的方式实现Parcelable
    //3.还有一种方法可以自定义生成的缓存
    androidExtensions {
        experimental = true
    }

    //使用viewbinding
    buildFeatures {
        viewBinding true
    }

    //确定java 版本
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

10.sourceSet

强大的gradle,通过sourceSets可以让开发者能够自定义项目结构,如自定义assets目录、java目录、res目录,而且还可以是多个,但要知道的是,sourceSets并不会破坏变体的合并规则,它们是分开的,sourceSets只是起到了“扩充”的作用。这里先摆一下sourceSets的常规使用:

java
复制代码
sourceSets {
	main {
		manifest.srcFile 'AndroidManifest.xml'
		java.srcDirs = ['src']
		aidl.srcDirs = ['src']
		renderscript.srcDirs = ['src']
		res.srcDirs = ['res']
		assets.srcDirs = ['assets']
	}
}

对于多渠道共用同一套assets资源文件这个问题,结合sourceSets,我们可以这么处理,步骤如下:

  1. 把共用的assets资源存放到一个渠道目录下,如free/assets。
  2. 修改sourceSets规则,强制指定china渠道的assets目录为free/assets。
java
复制代码
sourceSets {
	china {
		sourceSet.assets.srcDirs = ['src/free/assets']
	}
}

参考文章:

本文由 波鲁萨利诺.黄猿 原创发布于 阳光沙滩 , 未经作者授权,禁止转载
评论
0 / 1024
推荐文章
Linux 防火墙完全指南:从原理到多发行版实战
本文全面解析Linux防火墙的底层原理与主流工具配置,涵盖UFW、firewalld、iptables、nftables等方案,适合不同发行版用户。从基础概念到生产环境加固建议,助你掌握核心安全策略,确保服务器与网络的安全运行。
水上派对英语单词篇
探索FLOATOPIA水上派对的完整指南,涵盖签到流程、场地指引、安全须知、活动安排及夜场舞会等实用英语词汇与对话。无论是初学者还是老手,都能轻松掌握关键术语,享受完美水上体验。
麒麟操作系统下使用 virt-customize 重置虚拟机 root 密码实战
本文详细介绍了在麒麟操作系统环境下使用 virt-customize 工具重置 KVM 虚拟机 root 密码的完整流程,包含安装步骤、常见问题及解决方案,帮助运维人员高效处理密码遗忘或批量初始化场景,避免数据丢失。
浅析JS预编译-函数篇
本文详细讲解了JavaScript中函数的预编译过程,包括AO对象的创建、变量和函数声明的提升,以及执行阶段的变化。适合初学者了解JS执行机制,帮助深入理解代码运行逻辑。
访问Github的另一种姿势
本文介绍了如何通过Watt ToolKit等工具加速访问Github,适合对网络技术感兴趣的读者。内容涵盖工具介绍、下载和使用方法,以及一些实用技巧,值得一看。
使用Gulp压缩JS
本文详细介绍了如何使用Gulp压缩JavaScript文件,特别是支持ES6语法的处理方法。通过实际操作和效果对比,帮助开发者提升代码性能,适合对前端自动化工具感兴趣的读者。
使用Gulp压缩CSS
本文详细介绍了如何使用Gulp工具对CSS文件进行压缩,提升网页加载速度。适合需要优化静态资源的开发者,提供清晰的步骤和示例,帮助快速上手。
从0部署Nuxtjs项目
本文详细介绍了如何将Nuxt.js项目部署到公网,涵盖Node.js安装、环境配置、源码上传及使用PM2启动服务的全过程,适合开发者学习和实践。
Linux 命令行美化利器:tree 命令完全指南(安装 + 全部参数详解)
掌握 Linux 下的 `tree` 命令,快速直观地查看目录结构。本文详细讲解安装方法、参数含义及实战场景,适合开发者和系统管理员提升工作效率。
Linux常用命令(一)
本文详细介绍了Linux基础命令,包括文件操作、系统显示、网络状态、软件包管理等,适合初学者学习和查阅,是掌握Linux系统的实用指南。
大模型推理参数解码:温度、Top-p 与核采样如何塑造生成文本的灵魂
探索大语言模型的采样参数如何塑造生成内容,从温度到Top-p,从惩罚机制到熵控制,揭示背后的信息论原理与实践策略。了解如何通过参数调优,让AI既保持知识的严谨,又拥有创造力的自由。
记从0使用Claude code写代码
本文介绍了如何使用Claude Code搭配DeepSeek进行编程,详细讲解了安装Node.js、全局安装Claude、配置模型以及使用方法。对于开发者来说,这是一份实用的技术教程,尤其适合对AI编程工具感兴趣的读者。
Android-Studio-Gradle同步失败-Library为null的通用排查指南
遇到 Android Studio Gradle Sync 失败时,不要轻易删除全局缓存。本文详细解析了错误原因,并提供了一系列精准的排查步骤和解决方案,帮助开发者快速定位并解决问题,提升开发效率。
PHP实现密码加密
本文详细介绍了Bcrypt密码加密技术及其在PHP中的应用,帮助开发者提升用户密码的安全性。通过实际代码示例,展示了如何使用password_hash和password_verify函数进行密码加密与验证,是学习网络安全知识的实用指南。
WordCloud效果,滚动标签
本文详细介绍了如何在Vue项目中集成WordCloud组件,包括依赖安装、属性配置和使用方法。适合开发者学习如何实现数据可视化功能,提升项目交互体验。
从0使用WordPress搭建一个优美的网站
本文详细介绍了如何使用WordPress搭建一个美观的网站,从安装到主题配置和功能拓展,为读者提供了实用的操作指南。无论是初学者还是有一定经验的开发者,都能从中获得有价值的参考。
JS实现在网站底部添加运行时间
想知道如何在网站底部显示运行时间?本文详细讲解了通过JavaScript实现这一功能的方法,包括时间计算逻辑和代码实现。适合前端开发者学习参考,轻松为网站添加实用功能。
在Vercel上部署Hexo博客
本文详细介绍了如何在Vercel上快速部署Hexo博客,无需后端服务即可实现高效发布。相比传统方式,省去了手动生成和上传静态文件的步骤,更加便捷。适合想要搭建个人博客的开发者参考。
从0搭建一个Hexo博客
本文详细介绍了Hexo博客框架的使用方法,从安装到部署全流程讲解,适合想快速搭建个人博客的技术爱好者。内容清晰易懂,是入门Hexo的理想指南。
离线设备激活方案:古老的 Windows 光盘激活,离线算法授权等
本文深入解析了离线激活的核心原理与实现方式,从历史案例到现代技术,全面剖析了如何在无网络环境下确保软件授权的安全性。通过设备指纹、授权文件校验等手段,为开发者提供了可复用的架构设计思路,适用于工业、医疗等对网络依赖较低的场景。
Hexo实现生成站点地图
想为你的Hexo博客添加站点地图功能吗?本文详细介绍了如何通过安装插件和配置文件来实现,适合没有内置该功能的新主题或自定义主题的用户。简单步骤助你提升搜索引擎优化效果。
Hexo实现代码压缩
本文分享了如何通过Hexo插件优化博客性能,详细介绍了安装和配置过程,帮助提升网页加载速度。适合对网站优化感兴趣的开发者阅读。
记一次 GitHub 幽灵协作者大清洗:强制重写 Git 历史与穿透 CDN 缓存实践
本文详细讲解了如何解决GitHub上出现的‘幽灵协作者’问题,通过重写Git历史和穿透CDN缓存,彻底清理错误提交记录。适合开发者学习如何高效管理项目历史与优化仓库信息。
从一行 `native` 堆栈追到 InstallReferrer:一次主线程 ANR 的排查全过程
本文详细记录了一次主线程ANR的排查过程,从一行native堆栈追踪到InstallReferrer服务调用。通过分析堆栈、源码和系统调用,揭示了归因SDK在主线程同步调用Play商店服务导致的ANR问题,并提供了多维度的解决方案。对于Android开发者来说,是一篇深入浅出的技术实践指南。
Linux从 HelloWorld 到数据库服务注册
本文详细解析了Linux系统中服务注册的概念与实现,通过一个简单的Hello World示例,帮助读者理解如何将程序注册为systemd服务,并掌握相关操作命令。无论是数据库还是其他应用,了解服务注册机制都是系统管理的重要基础。
学习虚拟机的笔记
linux ps 命令详解,跟着敲一次就掌握了
深入了解 Linux 中最常用的进程查看命令 `ps`,掌握其各种用法和参数,适用于系统管理和故障排查。从基础到高级,全面解析 `ps` 的使用技巧,帮助您提升 Linux 运维技能。
ObjectMapper 入门:Java 对象与 JSON 之间的「翻译官」
了解ObjectMapper在Java中如何实现对象与JSON的转换,掌握其在Spring Boot项目中的应用及常见使用场景。本文详细解析了序列化/反序列化过程、API用法、与Spring MVC的关系以及与其他JSON库的对比,适合开发者快速上手和深入理解。
服务器一次中病毒的记录
本文详细描述了一次服务器异常流量的排查过程,发现大量外部IP与内部服务建立连接,疑似存在恶意程序。通过分析日志和图片,确认为恶意程序导致带宽占用过高,最终通过备份和删除操作解决问题。文章提供了技术排查思路和解决方案,对系统维护具有参考价值。
JavaWeb微服务脚手架搭建
本文介绍了构建微服务架构时常用的开发模板和核心组件,涵盖技术选型、依赖配置及版本差异分析。通过合理选择 Java 和 Spring Boot 版本,可以显著提升开发效率和系统性能,是开发者不可错过的实践指南。