应用场景:经常发版本经常徘徊于测试API和正式API之间,一不小心太着急打包了,忘记改为正式API,又得重新打包。
问题:能不能一次操作,产出多个APK对应不同API。
重点:一切都在model的build.gradle
方法一
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
dev{
applicationIdSuffix ".dev"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
applicationIdSuffix ".debug"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors{
//自定义名字 但是不能和上面buildType中相同,不然Gradle编译会不通过。在这里使用了『flavors_』前缀以便区分。
flavors_release{
// manifestPlaceholders中写到的『str』,『package_name』不支持用大写,否则Gradle编译会不通过。
// 这里所设置的变量可以直接使用在『AndroidManifest.xml』中,使用方式为:${package_name}
// android:label="${package_name}"
manifestPlaceholders = [str:"releaseStr",app_name:"appname.release"]
// 这里的参数是为了在 java 代码中使用,具体的使用方式为:context.getResources().getString(R.string.strKey);
resValue("string" , "host","http://www.sun.com")
}
flavors_dev{
manifestPlaceholders = [str:"devStr",app_name:"appname.dev"]
resValue("string" ,"host","http://www.google.com")
}
flavors_debug{
manifestPlaceholders = [str:"devStr",app_name:"appname.debug"]
resValue("string" , "host","http://www.baidu.com")
}
}
划重点
applicationIdSuffix 看起来不一样,仅仅为了区分版本,applicationId还是一样 ,以上有三个版本其实就只能装一个在同一个手机上。
manifestPlaceholders 类似一个Map,不同版本下对应不同的值如上面想改变不同版本的app的名字,那么代码如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fredro.shiji.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="${app_name}"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
manifest中的重点在于android:label=”${app_name}”不同版本对应的app名字就会是appname.release;appname.dev;appname.debug。如果要其它类似的结果也可以用manifestPlaceholders考虑考虑。
不同版本有了,对应的API是怎么处理?
resValue("string" , "host","http://www.sun.com")
resValue("string" , "host","http://www.baidu.com")
resValue("string" ,"host","http://www.google.com")
不同版本对应的resValue中的value就是对应的API,resValue取值类似于context.getResources().getString(R.string.strKey);
import static com.fredro.shiji.myapplication.R.string.host;
public class MainActivity extends AppCompatActivity {
private TextView tv;
private static String HOST;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
// tv.setText(host);
// Contast.HOST = tv.getText().toString();
HOST = getString(host);
// tv.setText(host + "\n" + "HOST:" + Contast.HOST);
tv.setText(HOST);
}
}
写完resValue(“string” , “host”,”http://www.sun.com“)后
再同步编译才会有“host”这个字段,才能引入
import static com.fredro.shiji.myapplication.R.string.host;
将资源String id转换成字符串方法:
String a=context.getString(resId);
方法二
创建不同版本的文件夹,然后包名一样,类名也一样,主要API接口不一样。还是build.gradle修改
productFlavors {
product {
applicationId 'product.com.joe.differentrequest'
versionName '1.0-product'
}
uat {
applicationId 'uat.com.joe.differentrequest'
versionName '1.0-uat'
}
nduat {
applicationId 'uduat.com.joe.differentrequest'
versionName '1.0-uduat'
}
}
此方法打包出来的三个apk可以同时安装在一个手机中。因为applicationId不一样。
参考:
http://blog.csdn.net/xx326664162/article/details/48467343
http://www.jianshu.com/p/81eff804d1b8