The book goes back to the Component Development Specification for Android Modular Design. The component development specification has been defined, but there is still a problem: how to count the components used in our packaged component library in the current project?
Because the company has more than a dozen projects under development in parallel, which components are used in each project, and what versions? Without this information, it is difficult to move the component construction effort forward. But having each project leader periodically report the versions of each component is not only low, but also inefficient.
Wouldn’t it be nice to have Gradle scripts do this repetitive, mechanical work for us?
And here it comes:
import groovy.json.JsonBuilder
// User-defined report interval Currently, the interval is once every three days
def reportTimeInterval = 3 * 24 * 60 * 60 * 1000
def reportInfo = new ReportInfo()
def isNeedReport = false
// Iterate over all submodules
subprojects {
project.afterEvaluate {
// Collect only the dependencies under Application
def isApp = project.plugins.hasPlugin("com.android.application")
if (isApp) {
isNeedReport = checkReportStatus(reportTimeInterval)
if (isNeedReport) {
println("-- > Start detecting dependent components...")
reportInfo.projectName = "${project.rootProject.name}"
reportInfo.reportTime = new Date().time
// Get the configuration information
project.configurations.all {
// Iterate over all dependencies, including indirect dependencies
resolutionStrategy.eachDependency { details ->
analysisDeps(details, reportInfo)
}
}
} else {
println("-- > Less than the set interval, no need to report dependency, end of the test")}}}}// Analyze dependencies and generate report objects
def analysisDeps(details, reporter) {
def group = details.requested.group
def name = details.requested.name
def version = details.requested.version
def library = "$group:$name"
// The component information that you want to report can be filtered, and the unconcerned content can be filtered out
// You can define multiple filtering rules
if (group == "com.company.android") {
if (reporter.libraries.containsKey(library)) {
def libraryInfo = reporter.libraries.get(library)
libraryInfo.versions.add("$version")}else {
def libraryInfo = new ReportLibraryInfo()
libraryInfo.group = group
libraryInfo.name = name
libraryInfo.versions.add("$version")
reporter.libraries.put(library, libraryInfo)
}
}
}
// Determine whether an update is needed
def checkReportStatus(interval) {
Properties pro = new Properties()
// Read the last reported time from depsCache. Properties temporary file
def proFile = project.rootProject.file('.depsCache.properties')
// If the file does not exist
if(! proFile.exists()) { proFile.createNewFile() updateReportTime(pro, proFile)return true
}
InputStream inputStream = proFile.newDataInputStream()
pro.load(inputStream)
def preRecordTime = pro.getProperty("preRecordTime")
if (preRecordTime == null) {
updateReportTime(pro, proFile)
return true
}
def preRecordTimeLong = preRecordTime.toLong()
println(${new Date(preRecordTimeLong). Format ("yyyy-MM-dd HH:mm", TimeZone.getTimeZone("GMT+08:00")}")
def currentTime = new Date().time
def temp = currentTime - preRecordTimeLong
if (temp > interval) {
updateReportTime(pro, proFile)
return true
} else {
println("-- > < reporting interval, no detection dependency required")
return false}}// Update the last report time
def updateReportTime(properties, file) {
def currentTime = new Date().time
properties['preRecordTime'] = "$currentTime".toString()
properties.store(file.newWriter(), "\n This file is automatically generated. Do not manually modify it \n")}// After the gradle task is finished
gradle.buildFinished {
if (isNeedReport) {
reportDeps("${new JsonBuilder(reportInfo).toPrettyString()}")}}// Through the network request to use the component information reported to their own implementation of the server, do persistent processing, complete the use of the current project component information collection
def reportDeps(content) {
println("$content")
def post = new URL("http://localhost:3000/report").openConnection();
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type"."application/json")
post.getOutputStream().write(content.getBytes("UTF-8"));
def postRC = post.getResponseCode();
if (postRC == 200) { println(post.getInputStream().getText()); }}class ReportInfo {
String projectName
long reportTime
Map<String, ReportLibraryInfo> libraries = new HashMap<>()
}
class ReportLibraryInfo {
String group
String name
Set<String> versions = new HashSet()
}
Copy the code
Gradle script is ready, let’s name it depsReport. Gradle and import the script in the root directory of our project (we recommend hosting the script on the server and using remote dependencies) :
apply from: "depsReport.gradle"
Copy the code
This script is triggered when any Gradle command is run and generates a depscache.properties file that records the time of the report, which can be ignored to avoid committing to Git repository.
If every project has access to this script, the current component library usage of all projects will be counted. Finally, every project leader will not have to manually report every week. Sure enough, “laziness” is the first productivity