Android studio Android源码开发环境搭建
1 起因
android studio工具对java代码自动提示和搜索等功能,把服务的代码全部导入整个工程,在加载的过程特别耗时,只需要我们自己开发的一部分代码,通过grade脚本用scp命令在windows和linux之间复制文件,将android studio中的修改同步到服务器
如果需要将整个代码导入到Android studio中,可以参考下面这篇博客:
AndroidStudio源码开发环境搭建 - Gityuan博客 | 袁辉辉的技术博客
2 环境搭建
1 安装git工具, 将git 和git自带的bash全部加到windows环境变量中
2 scp免密在windows和Linux服务器之间复制文件
- ssh-copy-id命令把本地的ssh公钥文件添加到远程主机对应的账户下
cd ~/.ssh/
// remote_username = 远程Linux服务器用户名
// remote_ip = 远程linux服务器IP地址
ssh-copy-id -i ~/.ssh/id_rsa.pub remote_username@remote_ip
- 用scp命令测试看看是否配置OK
// remote_username = 远程Linux服务器用户名
// remote_ip = 远程linux服务器IP地址
scp local_file remote_username@remote_ip:remote_file
scp remote_username@remote_ip:remote_file .
3 项目配置
1 将android studio工程克隆或者下载到本地
https://github.com/980725866/android_frameworks
2 Android Studio 配置
// project config start
ext {
// 服务器用户名
userName = "ubuntu"
// 服务器IP
serverIp = "1.1.1.1"
// 服务器项目代码根目录路径
projectPath = "/home/ubuntu/Android/"
// 对应的board名
tartgetBoard = "t982_ar301"
SCP_PROJECT_PATH = "scp -p ${rootProject.ext.userName}@${rootProject.ext.serverIp}:${rootProject.ext.projectPath}/"
PROJECT_PATH = "${rootProject.ext.userName}@${rootProject.ext.serverIp}:${rootProject.ext.projectPath}/"
}
// project config end
4 拉取代码
FRAMEWORK_CODE
拉取服务器代码的路径定义在FRAMEWORK_CODE中,如果需要添加其它路径的代码,在FRAMEWORK_CODE 列表中修改既可。
def FRAMEWORK_CODE = [
"frameworks/base/core/",
"frameworks/base/services/"
]
点击运行pullFrameworkCode task,拉取服务器代码
pullFrameworkCode
pullFrameworkCode脚本根据FRAMEWORK_CODE中指定的路径从服务器copy到本地对应的路径下
task pullFrameworkCode() {
doLast {
println("pullFrameworkCode")
def out = new ByteArrayOutputStream()
def cmd = ""
for (filePath in FRAMEWORK_CODE) {
def scpCmd = "scp -rp " + PROJECT_PATH + filePath + "* " + filePath + ";"
def directoryPath = filePath.substring(0, filePath.lastIndexOf("/"))
def windowsDirectoryPath = directoryPath.replace("/", "\\")
def file = new File(rootProject.rootDir, windowsDirectoryPath)
if (!file.exists()) {
cmd += "mkdir -p " + directoryPath + ";"
}
cmd += scpCmd
}
cmd += "cd frameworks;git init;"
exec {
ExecSpec execSpec ->
executable 'bash'
args '-c', cmd
standardOutput = out
}
println(out.toString())
}
}
5 提交代码
1 拉取代码的脚步会创建git创库,用来add修改的差异文件,查看vesrsion control 确保创库配置对了。出错会显示红色
2 修改代码后,通过git add 添加到git仓库(*add显示为灰色或者git选项不能出来,说明version control配置不对 *)
3 点击 pushFrameworkCode 将git add的修改复制到服务器
pushFrameworkCode
通过git创库,获取已经add到创库的文件, 再用scp命令将add到创库的文件复制到服务器
task pushFrameworkCode() {
doLast {
println("pushFrameworkCode")
def dir = "frameworks/";
def out = new ByteArrayOutputStream()
// 通过git创库,获取已经add的文件同步到服务器, 只用scp修改的代码
def gitCmd = "git status -suno ."
exec {
workingDir '.\\frameworks'
commandLine 'cmd', '/c', gitCmd
standardOutput = out
}
if (out == null || out.equals("")) {
return
}
def cmd = ""
def filePaths = out.toString().split("\n")
for (tmpFilePath in filePaths) {
def filePath = tmpFilePath.substring(tmpFilePath.indexOf(' ') + 1).trim()
if (filePath == null || !filePath.endsWith(".java")) {
continue
}
def scpString = "scp -p ${dir}" + filePath + " " + PROJECT_PATH + "${dir}" + filePath + ";"
println("pushFrameworkCode " + scpString)
cmd += scpString
}
if (cmd.length() < 10) {
return
}
exec {
ExecSpec execSpec ->
executable 'bash'
args '-c', cmd
standardOutput = out
}
println(out.toString())
}
}
6 adb push到设备
服务器编译好后,通过pushFrameworkJar先从服务器下载jar等文件到本地,然后会自动通过adb push命令推送到对应的开发版上,重启
FRAMEWORK_JARS
FRAMEWORK_JARS中定义需要push的文件路径
def FRAMEWORK_JARS = [
"out/target/product/${rootProject.ext.tartgetBoard}/system/framework/framework.jar",
"out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm/boot-framework.art",
"out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm/boot-framework.oat",
"out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm/boot-framework.vdex",
// "out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm64/boot-framework.art",
// "out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm64/boot-framework.oat",
// "out/target/product/${rootProject.ext.tartgetBoard}/system/framework/arm64/boot-framework.vdex",
]
pullFrameworkJar
pullFrameworkJar将FRAMEWORK_JARS中定义的文件复制到本地;再通过pushFrameworkJar中的脚本用adb push到开发版或者手机上
task pullFrameworkJar() {
doLast {
println("pullFrameworkJar")
def out = new ByteArrayOutputStream()
def cmd = ""
for (filePath in FRAMEWORK_JARS) {
def scpCmd = SCP_PROJECT_PATH + filePath + " " + filePath + ";"
def directoryPath = filePath.substring(0, filePath.lastIndexOf("/"))
def windowsDirectoryPath = directoryPath.replace("/", "\\")
def file = new File(rootProject.rootDir, windowsDirectoryPath)
if (!file.exists()) {
cmd += "mkdir -p " + directoryPath + ";"
}
println(file.getPath())
cmd += scpCmd
}
println(cmd)
exec {
ExecSpec execSpec ->
executable 'bash'
args '-c', cmd
standardOutput = out
}
println(out.toString())
}
}
pushFrameworkJar
pushFrameworkJar依赖pullFrameworkJar任务
task pushFrameworkJar() {
dependsOn(pullFrameworkJar)
doLast {
println("pushFrameworkJar")
def tartgetBoard = "${rootProject.ext.tartgetBoard}"
def out = new ByteArrayOutputStream()
def cmd = "adb root;adb remount;"
for (filePath in FRAMEWORK_JARS) {
def windowsFilePath = filePath.replace("/", "\\")
def devicePath = filePath.substring(filePath.indexOf(tartgetBoard) + tartgetBoard.length() + 1)
println(windowsFilePath + " " + devicePath)
cmd += "adb push ${windowsFilePath} ${devicePath};"
}
cmd += "adb reboot"
println(cmd)
exec {
ExecSpec execSpec ->
executable 'bash'
args '-c', cmd
standardOutput = out
}
}
}
7 删除
如果开发完了这个项目,服务器上拉取下来的代码不再需要,需要下载其它的代码,可以执行cleanFramework task删除本地code和 git仓库
task cleanFramework() {
doLast {
println("cleanFramework")
def cmd = "rm out -rf;rm frameworks/* -rf;rm frameworks/.git -rf"
exec {
ExecSpec execSpec ->
executable 'bash'
args '-c', cmd
standardOutput = out
}
println(out.toString())
}
}