一切都是因为懒—Android Studio自动打包

2017-08-11  本文已影响470人  _compass

这是一篇在Mac上Android Studio自动打包脚本的产生以及优化的文章。

其实自动打包的脚本大家已经写的很多了,我这里只是一个总结,有需要的同学,可以参考一下。

起初我们项目有2个app(android,iOS各一个),测试版本加上线上版本,一共是4个app。打包app的时候,需要替换工程里的某些资源文件(例如服务器基地址,h5包等)。手工拷贝我打包过一次就再不想有第二次了,耗时太长,并且容易出错。所以当时写了一个简单的自动打包脚本:

1.脚本这么写:

1.1定义需要区分的类型:

buildtype=Sample-hd-ol
hosttype=ol

1.2.获取当前工作路径:

为什么要获取当前工作路径,而不是写死工程路径,是为了分支之后,我只需要找到编译脚本所在的位置,而不需要修改工程路径。
例如我现在脚本所在位置是Sample/Shell目录下,工程代码路径在Sample/SampleHD下,那么获取当前路径这么写:

#工作路径
current_dir=$(pwd)
echo $current_dir
cd $current_dir
cd ..
cd Sample/SampleHD
workspace_path=$(pwd)
#打印一下代码路径
echo $workspace_path

1.3.拷贝项目所需要的资源:

例如,我需要拷贝一个某个资源文件到工程:

#resource在工程里的路径
#拷贝resource路径
resource_path=/Users/Compass/Package/WebApp/${buildtype}/resource.zip
resource_workpath=${workspace_path}/app/src/main/assets/resource.zip

#拷贝resource到工程路径,强制替换
cp ${resource_path} ${resource_workpath}

1.4.编译之后,将app输出到指定目录:

#需要输出的app的路径
app_path=/Users/Compass/Package/app/$(date +%Y%m%d)

#以下为自动编译过程
#编译config名称
configname=samplerelease

#编译路径
build_path=./app/build/outputs/apk/app-${hosttype}-${configname}.apk

#apk名称
apk_name=${buildtype}.apk

# 进入要工作的文件夹
cd ${workspace_path}

# 清空
./gradlew clean

# 编译
./gradlew assemble${hosttype}${configname}

# 按照日期创建
mkdir ${app_path}

# 将编译出的结果拷贝到指定文件夹下
mv ${build_path} ${app_path}/${apk_name}

是不是很简单?这样就完成了,但是,你会发现编译不通过,因为graldle还没有配置,配置如下:

2.工程里这么配置:

2.1.工程里(gradle.properties),配置秘钥:

RELEASE_STORE_FILE=/Users/Compass/android/Key/wrkey.jks
RELEASE_STORE_PASSWORD=password
RELEASE_KEY_ALIAS=alias
RELEASE_KEY_PASSWORD=password

2.2. 在Module app的build.gradle里添加配置:

 signingConfigs {
        release{
            storeFile file (RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
        }
    }
 buildTypes {
        samplerelease {
            debuggable false
            jniDebuggable false
            signingConfig signingConfigs.release
            minifyEnabled false
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

上面的samplerelease,就是脚本里对应的:

./gradlew assemble${hosttype}${configname}

这句里的configname;其中hosttype是Flavors,如果不需要动态配置某些参数,可以不需要加。
添加Flavors,编译的时候,可根据ol,nt切换HOST_URL_VALUE,这个值在

productFlavors {
        ol {
            manifestPlaceholders = [HOST_URL_VALUE: "https://www.xxx.xxx"]
        }
        nt {
            manifestPlaceholders = [HOST_URL_VALUE: "http://172.xxx.xxx.xxx"]
        }
    }

HOST_URL_VALUE需要在AndroidManifest.xml里添加:

 <meta-data
            android:name="HOST_URL"
            android:value="${HOST_URL_VALUE}" />

在你的代码里,这么写就可以动态获取到在gradle里配置的值了:

  public static String getHost(Context context) {
        String hostURL = getAppMetaData(context, "HOST_URL");
        if (hostURL != null) {
            return hostURL;
        }

        return DEFUALT_HOST;
    }

这样,gradle里也配置好了,脚本也写好了,打开控制台,运行一下,试试看:

cd /Users/Compass/Work/Sample/Shell
./sample_hd_ol.sh

是不是发现有这个问题:

-bash: ./sample_hd_ol.sh: Permission denied

这是权限问题,输入下面命令就可以了:

 chmod 777 sample_hd_ol.sh

再次执行脚本,看看结果。
如果成功了,在输出目录下,就能看到打包好的apk了,比如,我这里是/Users/Compass/Package/app/20170811目录下:

image.png

这样,基本一个自动打包脚本就写好了。如果你有多个apk打包,可以写多个脚本文件批处理。

当我们的项目,从2个app,发展到现在需要编译8个app的时候,出现了新的问题:

太慢了,竟然需要35分钟!

平均一个app需要编译4分钟。找了一下原因,是因为我们工程里引用了很多公共库,编译器编译的时候都在线获取版本;以及每次Build都有一个新起一个JVM等原因。

参考这位同学的文章《加快gradle的编译速度总结-亲身经历》:
http://www.jianshu.com/p/200d55b4d40a

3.优化:

3.1开启守护进程

将工程的gradle.propertis复制出来,里面贴如下内容,然后此目录下,全局可以使用,例如我的:/Users/Compass/.gradle/

  // 开启线程守护,第一次编译时开线程,之后就不会再开了
  org.gradle.daemon=true 
  // 配置编译时的虚拟机大小
  org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8  
  // 开启并行编译
  org.gradle.parallel=true 
  // 启用新的孵化模式
  org.gradle.configureondemand=true  

加了这个配置之后,原先编译里的这个提示:

To honour the JVM settings for this build a new JVM will be forked. 
Please consider using the daemon: https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html.

就变成了:

Parallel execution with configuration on demand is an incubating feature.

3.2 Gradle离线配置

我将gradle包放入/Users/Compass/.gradle/下,指定Gradle home即可。这个目录也可以使用Android studio的安装目录:
/Applications/Android\ Studio.app/Contents/gradle/gradle-2.14.1
这里的gradle-2.14.1是我as里的gradle版本,你需要换成你自己的版本。


image.png

这两处修改了之后,编译速度就快多了,一个app1分钟:

image.png

我如果去掉./gradlew clean,不清空的话,编译速度更快,大概10秒就能编完:

image.png

恩,对于我2012年的电脑,在清空的情况下,1分钟我觉得已经可以接受了。8个app,大概10分钟吧。

这样,我就可以在分支N个版本的时候,打开一个脚本,能自动打包N个app了。

一切都是因为懒。

上一篇下一篇

猜你喜欢

热点阅读