Flutter工程的Android编译网速优化

2,889 阅读2分钟

致在安卓端开发Flutter的小伙伴:

当你苦哈哈搭建完Flutter环境以后,
当你急忙忙创建了第一个Flutter工程以后,
当你兴冲冲的写下:flutter run 以后,
漫长的等待开始了...                         ⣟

当然,你可以根据官方文档:Using Flutter in China进行一轮优化,解决Flutter联网慢的问题.

然而,当你在安卓设备上运行Flutter项目的时候仍然会遇到网络问题。

这是因为安卓编译过程中仍需要联网获取一些依赖类库。

优化方法如下:

手动优化android/build.gradle文件:

修改前:

    repositories {
        google()
        jcenter()
    }

修改后:

    repositories {
        maven { url 'https://maven.aliyun.com/repository/google'} // google()
        maven { url 'https://maven.aliyun.com/repository/jcenter'} // jcenter()
    }

需要注意的是build.gradle文件中有两个repositories需要修改:

第一个在buildscript中,

第二个在allprojects中。

如果你要维护的项目中包含很多组件, 每个组件中的build.gradle都需要这样的修改。 这样的话手动改起来就会很麻烦,当然你也可以用脚本.

用脚本自动优化:

你可以把脚本optimize_cn_network.py 放入你flutter工程根目录下的bin/中。

使用脚本优化的例子如下,你只需要输入“bin/optimize_cn_network.py android/”就可以了。

$ bin/optimize_cn_network.py android/
Optimizing cn network: /Volumes/user/cjf/w/ovo/flutterame/android/build.gradle
No line to optimize in file: /Volumes/user/cjf/w/ovo/flutterame/android/build.gradle

假设你的组件"gallery" 目录如下

├── README.md
├── android
├── flutterame.iml
├── ios
├── lib
├── modules
│   └── gallery
│       ├── .android
│       └── ...
├── pubspec.lock
├── pubspec.yaml
└── ...
    

此时需要输入的命令是:“bin/optimize_cn_network.py modules/gallery/.android”

$ bin/optimize_cn_network.py modules/gallery/.android        
Optimizing cn network: /Volumes/user/cjf/w/ovo/flutterame/modules/gallery/.android/build.gradle

bin/optimize_cn_network.py 工作原理

脚本会读取指定位置的build.gradle文件。

然后查找"repositories {"和"}"之间的google()和jcenter()找到后替换为

        maven { url 'https://maven.aliyun.com/repository/google'} // google()
        maven { url 'https://maven.aliyun.com/repository/jcenter'} // jcenter()

bin/optimize_cn_network.py 内容如下:

#!/usr/bin/env python3

import os
import sys
import re
from time import strftime, localtime
from ezutils.files import readlines, writelines
dir = os.path.abspath(os.path.dirname(__file__))
parent_dir = os.path.dirname(dir)


def replace_lines(target_reg, *, by_lines, begin_reg,  end_reg, in_lines):
    re_begin = re.compile(begin_reg)
    re_target = re.compile(target_reg)
    re_end = re.compile(end_reg)

    indexs = []
    state = 'find_begin'
    index = -1
    for line in in_lines:
        index += 1
        if state == 'find_begin' and re_begin.match(line):
            state = 'find_target'
            continue
        if state == 'find_target' and re_target.match(line):
            indexs.insert(0, index)
            state == 'find_end'
            continue
        if state == 'find_end' and re_end.match(line):
            state == 'find_begin'
            continue

    if len(indexs) == 0:
        return None

    new_lines = in_lines
    for index in indexs:
        new_lines = new_lines[:index]+by_lines+new_lines[index+1:]
    return new_lines


def optimize_cn_network(target_file):
    print(f'Optimizing cn network: {target_file}')
    lines = readlines(target_file)
    has_google = True
    new_lines = replace_lines(
        r'\s*google().*',
        by_lines=[
            "        maven { url 'https://maven.aliyun.com/repository/google'} // google()"],
        begin_reg=r'\s*repositories\s*{.*',
        end_reg=r'\s*}.*',
        in_lines=lines)

    if(new_lines == None):
        has_google = False
        new_lines = lines

    new_lines = replace_lines(
        r'\s*jcenter().*',
        by_lines=[
            "        maven { url 'https://maven.aliyun.com/repository/jcenter'} // jcenter()"],
        begin_reg=r'\s*repositories\s*{.*',
        end_reg=r'\s*}.*',
        in_lines=new_lines)

    if new_lines == None and not has_google:
        print(f"No line to optimize in file: {target_file}")
        return

    writelines(new_lines, f'{target_file}.tmp')
    current_time = strftime("%Y-%m-%d_%H:%M:%S", localtime())
    os.rename(target_file, f'{target_file}.backup_{current_time}')
    os.rename(f'{target_file}.tmp', target_file)


if __name__ == "__main__":
    if len(sys.argv) == 1:
        print(
            "Input android project dir(example: 'android/' or 'modules/gallery/.android' ):")
        target_dir = input()
    else:
        target_dir = sys.argv[1]

    target_file = os.path.join(parent_dir, target_dir, 'build.gradle')
    optimize_cn_network(target_file)