使用gradle实现Android项目debug版与release版共存

来源:互联网 发布:picsart知乎 编辑:程序博客网 时间:2024/06/02 19:53

在Android项目中,默认debug版与release版的包名相同,从而导致debug版与release版两者不能共存,为了方便开发时的调试,通过gradle我们可以实现让两者在一台手机上共存

配置app目录下的build.gradle文件:

android {    ......    buildTypes {    ......        debug {            //为debug版本的包名添加.debug后缀            applicationIdSuffix ".debug"            ......        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在debug节点里添加这个配置后,debug版本的apk包名会自动加.debug后缀,比如原本包名为com.example.application的应用,debug包名为com.example.application.debug

权限重复的问题

如果项目中使用了第三方库,而且在AndroidManifest.xml中声明了权限,例如个推

<permission    android:name="getui.permission.GetuiService.package_name"    android:protectionLevel="normal"/>
  • 1
  • 2
  • 3

android5.0以上安装应用时会报duplicate permission exception,所以要保证debug和release安装包的permisson name不同,因此我们可以使用applicationId字段,使用方式如下:

<permission    android:name="getui.permission.GetuiService.${applicationId}"    android:protectionLevel="normal"/>
  • 1
  • 2
  • 3

provider authorities

<provider    android:name="com.igexin.download.DownloadProvider"    android:authorities="downloads.package_name"    android:exported="true"    android:process=":pushservice"/>
  • 1
  • 2
  • 3
  • 4
  • 5

同样也可以使用applicationId字段来替换

    android:authorities="downloads.${applicationId}"
  • 1

使用manifestPlaceholders属性来替换

但是不是所有的属性都能用applicationId来替换,比如融云这样的第三方库
可以看到如下data节点内的host=”package_name”就不能使用applicationId字段来替换

<activity            android:name=".activity.navigation.ConversationListActivity"            android:screenOrientation="portrait"            android:windowSoftInputMode="stateHidden|adjustResize">            <intent-filter>                <action android:name="android.intent.action.VIEW"/>                <category android:name="android.intent.category.DEFAULT"/>                <data                    android:host="package_name"                    android:pathPrefix="/conversationlist"                    android:scheme="rong"/>            </intent-filter>        </activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

因此我们可以使用manifestPlaceholders属性,manifestPlaceholders顾名思义manifest占位符,上面说的${applicationId}就是gradle自带的manifest占位符,当然我们也可以自定义manifest占位符
分别在release和debug节点下添加manifestPlaceholders属性如下所示:

android {    ......    buildTypes {    ......     release {            .......            manifestPlaceholders = [                    APP_NAME      : "@string/app_name",                    APPLICATION_ID: "@string/application_id"            ]        }        debug {            //为debug版本的包名添加.debug后缀            applicationIdSuffix ".debug"            manifestPlaceholders = [                    APP_NAME      : "@string/app_name_debug",                    APPLICATION_ID: "@string/application_id_debug"            ]            ......        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在项目的values/strings.xml文件里添加如下:

<string name="app_name">MyApplication</string>    <string name="app_name_debug">MyApplicationDebug</string>    <string name="application_id">com.example.myapplication</string>    <string name="application_id_debug">com.example.myapplication.debug</string>
  • 1
  • 2
  • 3
  • 4

然后将data节点内的host=”package_name”替换为 host=”${APPLICATION_ID}”

<activity            android:name=".activity.navigation.ConversationListActivity"            android:screenOrientation="portrait"            android:windowSoftInputMode="stateHidden|adjustResize">            <intent-filter>                <action android:name="android.intent.action.VIEW"/>                <category android:name="android.intent.category.DEFAULT"/>                <data                    android:host="${APPLICATION_ID}"                    android:pathPrefix="/conversationlist"                    android:scheme="rong"/>            </intent-filter>        </activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这样就能在打包release版本时包名使用release的包名,debug版本使用debug包名

app_name也同理,可以将android:label里的内容替换成manifestPlaceholders变量,如下所示:

android:label="${APP_NAME}"
  • 1

这样gradle编译时就会自动替换app_name

动态打包so包

apk的大小永远是开发者头疼的问题,而so包就是apk安装包体积过大的主要原因之一,因此很多开发者都会将一些用不到的so包去除,从而减少apk体积,比如x86的so包,但是如果你需要使用Android官方提供的模拟器来测试你的应用的话,那x86的so包是必不可少的,因此这里给出一个解决方案:

就是release版本打包时不包含x86的so包,减小正式版apk的体积,debug版本则包含x86的so包,方便在官方模拟器上测试

android {    ......    buildTypes {    ......     release {            .......            //设置release版本只包含armeabi和armeabi-v7a的so包            ndk {                abiFilters "armeabi", "armeabi-v7a"            }        }        debug {            ......            //设置debug版本包含x86的so文件            ndk {                abiFilters "armeabi", "armeabi-v7a", "x86"            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

转自:http://blog.csdn.net/lj402159806/article/details/54955431

阅读全文
0 0