通过Gradle实现一套代码开发不同特性的APK

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    signingConfigs {
        release {
            storeFile file(RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
        }
    }
    defaultConfig {
        applicationId "me.ghui.gradledemo"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            zipAlignEnabled false
        }
    }
    productFlavors {
        pay {
            applicationId "me.ghui.gradledemo.pay"
        }
        free {}
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.2'
    compile 'com.jpardogo.googleprogressbar:library:+'
    compile 'com.mcxiaoke.volley:library:1.0.+'
    compile 'com.jakewharton:butterknife:6.1.0'
}
我对pay flavor中的包名做了修改,free中没有做单独设置它会使用defaultconfig中定义的包名,这就解释了为什么我可以同时将这两个apk装到手机上。

那么如何实现pay , free 对应不同的特性呢,这里要引入另外一个概念—— “SourceSets”可以到这里了解,每个flavor都可以对应一个Sourceset,你可以在与src/main同级的目录下新建另外两个目录pay,free这里面可以放各自特性相关的代码,然后这些代码会与main下面的代码按照一定的规则进行合并,最终组成当前variant对应的完整代码。main,pay,free就是3个Sourceset 如下图:


你最终能编译出的apk的数量是由productflavor与BuildType决定的,虽然我这里没有定义Buildtype但gradle默认提供了两种buildType —— debug,release,所以,一共可以编译出4种apk,你可以到Android Studio 的BuildVariants面板中查看如下图:

实际上在你上图中的面板中切换variant时,Android视图下对应的代码是会发生变化的,这里显示出的代码就是你当前variant所拣取的代码,可以看到这里我选择编译paydebug上面的代码就由main+pay下面的代码组成了

在pay下面的ImgViewer中我使用了googleprogressbar而在free下的ImgViewer中我使用了普通的Progressbar,代码如下:

   GoogleProgressBar mProgressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_img_viewer);
        mProgressBar = (GoogleProgressBar) findViewById(R.id.google_progress);
        mProgressBar.setIndeterminateDrawable(getRandomProgressDrawable());
        onLoadImg();
    }
当然了pay与free下面对应的Imgviewer的布局文件也是不同的在各自的下面都有一个activity_img_viewer.xml pay下面是:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context="me.ghui.gradledemo.ImgViewer">
    <ImageView
            android:id="@+id/networkImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/waitting"
            android:layout_centerHorizontal="true" />
    <com.jpardogo.android.googleprogressbar.library.GoogleProgressBar
            android:id="@+id/google_progress"
            android:layout_centerInParent="true"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            />
</RelativeLayout>

free下面就是普通的progressbar,这里就不再贴了。 至于为什么app-name与app-icon不同那是因为我在pay ,free下面都各自添加了不同的app-name 与app-icon,在编译对应variant时gradle会去做选取。实际上buildtype也可以对应自己的sourceset,也可以有自己的代码。

上面说到了合并规则,下面总结一下:

图片、音频、 XML 类型的 Drawable 等资源文件,将会进行文件级的覆盖 字符串、颜色值、整型等资源以及 AndroidManifest.xml ,将会进行元素级的覆盖 代码资源,同一个类, buildTypes 、 productFlavors 、 main 中只能存在一次,否则会有类重复的错误 覆盖等级为:buildTypes > productFlavors > main





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值