Windows下载AOSP

关于repo

repo只是谷歌做的,方便下载安卓源码的工具,本质上是对下载清单进行批量处理,然后使用git克隆。
在windows上下载源码只需要自己处理即可。

具体做法

首先使用git克隆安卓源码清单

git clone https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest

随后进入manifest目录,查看所有tag

git tag

在这里插入图片描述

tag名就是安卓源码的版本,选择你要的版本,记下来。例如android-13.0.0_r9
随后切换分支

git checkout android-13.0.0_r9

在这里插入图片描述
记住文件夹中的default.xml的路径
以上操作完成了清单的下载,接下来我们只需要执行按清单下载的操作即可。
我提供两个我编写的脚本,一个python环境,一个golang环境。
注意:该脚本不支持断点续传,如需使用,请保持网络环境良好或自行修改脚本。

Python环境

该Python下载脚本仅支持单线程下载,不过git仍可以跑满你的网速

import xml.dom.minidom
import os
from subprocess import callversion = "android-13.0.0_r9"# 1. 源码要保存的路径
rootdir = "D:/AOSP/"+version# 2. git 的路径
git = r"C:\Program Files\Git\cmd\git.exe"# 3. default.xml 的路径
dom = xml.dom.minidom.parse(r"D:\AOSP\manifest\default.xml")
root = dom.documentElement# 4. 只支持单一镜像源
prefix = git + " clone https://aosp.tuna.tsinghua.edu.cn/"
suffix = ".git"if __name__ == '__main__':if not os.path.exists(rootdir):os.mkdir(rootdir)for node in root.getElementsByTagName("project"):os.chdir(rootdir)d = node.getAttribute("path")last = d.rfind("/")if last != -1:d = rootdir + "/" + d[:last]if not os.path.exists(d):os.makedirs(d)os.chdir(d)cmd = prefix + node.getAttribute("name") + suffix# 单线程下载call(cmd)

Golang环境

该golang脚本支持从多个镜像站并发下载,可限制每个镜像站同时下载的线程个数,以及总线程个数。
注意: * 总线程个数应小于等于各个镜像站线程个数相加*
resource.go

package mainimport ("sync"
)type Resource struct {Url  stringLock chan struct{}
}type ResourcePool struct {resources []*Resourcecond      *sync.Cond
}func NewResourcePool(list []*Resource) *ResourcePool {pool := &ResourcePool{cond: sync.NewCond(&sync.Mutex{}),}pool.resources = listreturn pool
}func (pool ResourcePool) GetResource() *Resource {pool.cond.L.Lock()defer pool.cond.L.Unlock()for {for _, resource := range pool.resources {select {case resource.Lock <- struct{}{}:return resourcedefault:continue}}pool.cond.Wait()}
}func (pool ResourcePool) ReleaseResource(resource *Resource) {<-resource.Lockpool.cond.Signal()
}

main.go

package mainimport ("encoding/xml""flag""fmt""log""os""os/exec""path/filepath""strings""sync"
)type Project struct {XMLName xml.Name `xml:"project"`Name    string   `xml:"name,attr"`Path    string   `xml:"path,attr"`
}type Manifest struct {XMLName xml.Name  `xml:"manifest"`Project []Project `xml:"project"`
}var (concurrentNum introotDir       stringmanifestPath  stringwg sync.WaitGroup
)var resourceA = &Resource{Url: "https://mirrors.bfsu.edu.cn/git/AOSP/%s.git", Lock: make(chan struct{}, 4)}
var resourceB = &Resource{Url: "https://aosp.tuna.tsinghua.edu.cn/%s.git", Lock: make(chan struct{}, 3)}//var resourceC = &Resource{Url: "https://mirror.nju.edu.cn/%s.git", Lock: make(chan struct{}, 3)}//var resourceC = &Resource{Url: "https://mirrors.shanghaitech.edu.cn/%s.git", Lock: make(chan struct{}, 3)}func init() {flag.IntVar(&concurrentNum, "concurrentNum", 7, "Number of concurrent goroutines")flag.StringVar(&rootDir, "root", "D:/AOSP/android-13.0.0_r9", "Root dir of AOSP.")flag.StringVar(&manifestPath, "manifest", "D:/AOSP/manifest/default.xml", "Manifest of AOSP.")
}func errorHandle(str string, err error) {if err != nil {log.Fatalf("Failed to %s: %v", str, err)os.Exit(-6)}
}func main() {flag.Parse()manifestXML, err := os.ReadFile(manifestPath)errorHandle("Read manifest file", err)var manifest Manifesterr = xml.Unmarshal(manifestXML, &manifest)errorHandle("Parse manifest XML", err)err = os.MkdirAll(rootDir, 0755)errorHandle("Create root directory", err)sem := make(chan struct{}, concurrentNum)pool := NewResourcePool([]*Resource{resourceA, resourceB,})for _, node := range manifest.Project {wg.Add(1)go func(project Project) {defer wg.Done()sem <- struct{}{}defer func() { <-sem }()cmdDir := rootDird := project.Pathlast := strings.LastIndex(d, "/")if last != -1 {d = filepath.Join(rootDir, d[:last])if err := os.MkdirAll(d, 0755); err != nil {errorHandle("Create d directory", err)}cmdDir = d}resource := pool.GetResource()if resource == nil {fmt.Println("No resource available")os.Exit(2)return}cmd := exec.Command("git", "clone", fmt.Sprintf(resource.Url, project.Name))cmdDir = strings.ReplaceAll(cmdDir+"\\", "/", "\\")cmd.Dir = cmdDirif err := cmd.Run(); err != nil {fmt.Printf("Failed to clone node: %v %s \n", err, cmd)return}pool.ReleaseResource(resource)fmt.Printf("Cloned node: %s \n", project.Name)}(node)}wg.Wait()
}

截至到23年10月3日,完全可用的镜像站仅剩清华,其他AOSP的镜像或多或少均有问题
python的脚本足矣,经测试,均速16m/s,一晚上可以下载好android-13.0.0_r9的所有源码
go的脚本推荐大家不要乱用,过多的下载进程会对镜像站造成巨大的负载
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

产品经理需要掌握哪些产品专业知识?

作为产品经理&#xff0c;最重要的是洞察客户的需求、理解客户的需求、掌握客户的需求&#xff0c;所以&#xff0c;第一件事情就是要有清晰的战略方向&#xff0c;我们到底梦想是什么&#xff1f;要做什么&#xff1f;能做什么&#xff1f;在哪儿做&#xff1f;谁负责去做&…

为什么mac上有的软件删除不掉?

对于Mac用户来说&#xff0c;软件卸载通常是一个相对简单的过程。然而&#xff0c;有时你可能会发现某些软件似乎“顽固不化”&#xff0c;即使按照常规方式尝试卸载&#xff0c;也依然存在于你的电脑上。这到底是为什么呢&#xff1f;本文将探讨这一问题的可能原因。 1.卸载失…

buuctf-[WUSTCTF2020]CV Maker 文件上传漏洞

打开环境 随便登录注册一下 进入到了profile.php 其他没有什么页面&#xff0c;只能更换头像上传文件&#xff0c;所以猜测是文件上传漏洞 上传一句话木马看看 <?php eval($_POST[a]);?>回显 搜索一下 添加文件头GIF89a。上传php文件 查看页面源代码&#xff0c;看…

求推荐好用的可视化大屏软件?强推奥威BI

在博览中心、会议中心、监控中心等场合下&#xff0c;经常看到很多炫酷的企业可视化大屏&#xff0c;将复杂的企业数据可视化展现&#xff0c;高大上、实用性一个不缺。那&#xff0c;可视化大屏做得好的软件有哪些&#xff1f;首推奥威BI软件。 奥威BI软件&#xff1a;零编程…

数据结构与算法(持续更新)

线性表 单链表 单链表的定义 由于顺序表的插入删除操作需要移动大量的元素&#xff0c;影响了运行效率&#xff0c;因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素&#xff0c;不需要使用地址连续的存储单元&#xff0c;因此它…

Flink---12、状态后端(HashMapStateBackend/RocksDB)、如何选择正确的状态后端

星光下的赶路人star的个人主页 大鹏一日同风起&#xff0c;扶摇直上九万里 文章目录 1、状态后端&#xff08;State Backends&#xff09;1.1 状态后端的分类&#xff08;HashMapStateBackend/RocksDB&#xff09;1.2 如何选择正确的状态后端1.3 状态后端的配置 1、状态后端&am…

APP自动化之Poco框架

今天给大家介绍一款自动化测试框架Poco&#xff0c;其脚本写法非常简洁、高效&#xff0c;其元素定位器效率更快&#xff0c;其本质基于python的第三方库&#xff0c;调试起来也会非常方便&#xff0c;能够很好的提升自动化测试效率&#xff0c;节省时间。 (一&#xff09;背景…

Zabbix 监控系统安装和部署

Zabbix 监控系统安装和部署 一、zabbix 是什么&#xff1f;1.1、zabbix 监控原理&#xff08;重点&#xff09;1.2、Zabbix 6.0 新特性1.3、Zabbix 6.0 功能组件1.4、数据库1.5、Web 界面1.6、Zabbix Agent1.7、Zabbix Proxy1.8、Java Gateway 二、部署Zabbix 6.02.1、 解决 za…

SQL监控工具

什么是 SQL 监控 SQL 监视是跟踪和分析整个 MSSQL 生态系统的过程&#xff0c;以识别性能问题并防止依赖数据库的应用程序变慢和/或遇到中断&#xff0c;它有助于获取有关 SQL 服务器的数据库会话、查询、作业、CPU 和内存资源、群集、配置和可用性组的信息。 为什么 MSSQL 监…

Redis-缓存穿透,缓存击穿,缓存雪崩

缓存穿透&#xff0c;缓存击穿&#xff0c;缓存雪崩 缓存穿透处理方案解决方案1 缓存空数据解决方案2 布隆过滤器 缓存击穿处理方案解决方案 1 互斥锁解决方案2 逻辑过期 缓存雪崩处理方案解决方案 1 给不同的key的过期时间设置添加一个随机值&#xff0c;降低同一个时段大量ke…

cv2.split函数与cv2.merge函数

split函数用于图像BGR通道的分离 merge函数用于可将分开的图像通道合并到一起 1.split函数的使用 这是原图&#xff0c;我们使用split函数对其三个通道进行分离。 注意&#xff1a;split函数分离通道的顺序是B、G、R。 以下方法是将三个通道的值都设置为与某一个通道相同。…

基于双二阶广义积分器的三相锁相环(DSOGI-PLL)Simulink仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

虚拟机模拟部署服务器

1、下载安装vmware 15 &#xff08;win7最高支持版&#xff09; 2、下载安装CentOS 配置2核2g&#xff08;最少&#xff09;磁盘100g&#xff08;不会实际占有&#xff09;选择时区配置分区 https://blog.csdn.net/qq_35363507/article/details/127390889 &#xff08;/boot …

Java 华为真题-小朋友分班

需求&#xff1a; 题目描述 幼儿园两个班的小朋友在排队时混在了一起&#xff0c;每位小朋友都知道自己是否与前面一位小朋友同班&#xff0c;请你帮忙把同班的小朋友找出来小朋友的编号是整数&#xff0c;与前一位小朋友同班用Y表示&#xff0c;不同班用N表示学生序号范围(0&…

旁注、越权、跨库、CDN相关

旁注原理 在同一服务器上有多个站点&#xff0c;我们要攻击的这个站点假设没有漏洞&#xff0c;我们可以攻击服务器上的任意一个站点&#xff0c;这个就是旁注 多端口需要知道IP 可以用尖刀&#xff0c;fscan,goby 探测 IP逆向查询&#xff08;知道域名&#xff09; 可通过pin…

Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…

基于or-tools的人员排班问题建模求解(JavaAPI)

使用Java调用or-tools实现了阿里mindopt求解器的案例&#xff08;https://opt.aliyun.com/platform/case&#xff09;人员排班问题。 这里写目录标题 人员排班问题问题描述数学建模编程求解&#xff08;ortoolsJavaAPI&#xff09;求解结果 人员排班问题 随着现在产业的发展&…

ToBeWritten之让响应团队参与并做好沟通

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…

数据结构与算法-前缀树

数据结构与算法-前缀树详解 1 何为前缀树 2 前缀树的代码表示及相关操作 1 何为前缀树 前缀树 又称之为字典树,是一种多路查找树,多路树形结构,是哈希树的变种&#xff0c;和hash效率有一拼&#xff0c;是一种用于快速检索的多叉树结构。 性质&#xff1a;不同字符串的相同…

力扣 -- 5. 最长回文子串

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:string longestPalindrome(string s) {int ns.size();vector<vector<bool>> dp(n,vector<bool>(n));//最长回文串的起始位置int start0;//最长回文串的长度int len0;for(int in-1;i>…