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 call

version = "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 main

import (
	"sync"
)

type Resource struct {
	Url  string
	Lock chan struct{}
}

type ResourcePool struct {
	resources []*Resource
	cond      *sync.Cond
}

func NewResourcePool(list []*Resource) *ResourcePool {
	pool := &ResourcePool{
		cond: sync.NewCond(&sync.Mutex{}),
	}
	pool.resources = list

	return 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 resource
			default:
				continue
			}
		}

		pool.cond.Wait()
	}
}

func (pool ResourcePool) ReleaseResource(resource *Resource) {
	<-resource.Lock

	pool.cond.Signal()
}

main.go

package main

import (
	"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 int
	rootDir       string
	manifestPath  string

	wg 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 Manifest
	err = 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 := rootDir

			d := project.Path
			last := 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 = cmdDir
			if 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的脚本推荐大家不要乱用,过多的下载进程会对镜像站造成巨大的负载
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在Windows下载Android源码,可以按照以下步骤进行操作: 1. 首先,你需要安装Git并设置好环境变量。你可以从Git官网下载并安装Git:https://git-scm.com/downloads 2. 打开命令提示符或Git Bash,并进入你想要保存Android源码的目录。 3. 使用以下命令克隆Android源码仓库的manifest文件: ``` git clone https://android.googlesource.com/platform/manifest.git ``` 如果你无法科学上网,你可以选择使用国内的清华数据源: ``` git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git ``` 4. 创建一个名为`python_download.py`的文件,并将以下代码复制到文件中: ```python import xml.dom.minidom import os from subprocess import call # 修改为源码要保存的路径 rootdir = "G:/android_source" # 设置git安装的路径 git = "C:/Program Files (x86)/Git/bin/git.exe" # 修改为第一步中manifest中default.xml保存的路径 dom = xml.dom.minidom.parse("G:/android_source/manifest/default.xml") root = dom.documentElement # 没有梯子使用清华源下载 prefix = git + " clone https://aosp.tuna.tsinghua.edu.cn/" suffix = ".git" 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) ``` 5. 修改`python_download.py`文件中的路径,将`rootdir`修改为你想要保存Android源码的路径,将`git`修改为你的Git安装路径。 6. 运行`python_download.py`文件,它将根据manifest文件中的信息下载Android源码。 请注意,下载Android源码需要较长的时间和大量的硬盘空间。建议你确保有足够的硬盘容量(至少100GB)来存储源代码。 #### 引用[.reference_title] - *1* *2* [Windows系统下载Android源码](https://blog.csdn.net/u014456004/article/details/120121296)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [windows下载Android系统源码](https://blog.csdn.net/liujun3512159/article/details/124136940)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的琦玉

打点钱,我会再努力的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值