对于不开发android的兄弟可能gradle的很多功能不会用,这里给出一个我自己用的多平台打包方案
1.自定义 buildConfigField
buildConfigField可以在不同平台下在打包时赋予不同的值 ,类似cc.sys.platform
defaultConfig {
buildConfigField "boolean", "M4399_AD", "false";
buildConfigField "boolean", "TT_AD", "true";
buildConfigField "boolean", "M233_AD", "false";
buildConfigField "boolean", "VIVO_AD", "false";
}
我这里是广告相关的配置,你们可以自由随便定义,
定义以后可以在java代码中使用
例如根据 不同的平台初始化不同的广告sdk
if(BuildConfig.M4399_AD) {
AdUnionSDK.init(this, Constants.M4399_APPID, new OnAuInitListener() {
@Override
public void onSucceed() {
isADInit = true;
Log.i("AdUnionSDK", "successed");
}
@Override
public void onFailed(String s) {
Log.i("AdUnionSDK", "onFailed");
}
});
} else if (BuildConfig.TT_AD) {
TTAdSdk.init(this,
new TTAdConfig.Builder()
.appId(Constants.TT_APPID)
.useTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
.allowShowNotify(true) //是否允许sdk展示通知栏提示
.allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
.directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G, TTAdConstant.NETWORK_STATE_4G) //允许直接下载的网络状态集合
.supportMultiProcess(false) //是否支持多进程,true支持
//.httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
.build(), new TTAdSdk.InitCallback() {
@Override
public void success() {
}
@Override
public void fail(int i, String s) {
}
});
} else if (BuildConfig.M233_AD) {
MetaAdApi.get().init(this, "1247372502", new InitCallback() {
@Override
public void onInitSuccess() {
}
@Override
public void onInitFailed(int i, String s) {
}
});
}
1.定义productFlavors
在每个Flavor中可以设置这个渠道的参数,比如包名,版本号之类的
productFlavors {
google {
}
baidu {
}
oppo {}
vivo {
minSdkVersion 21
applicationId "com.hate.game.vivo"
}
huawei {}
xiaomi {}
m360 {}
yyb {}
pp {}
sam {}
m4399 {
}
taptap {}
hykb {}
m233 {
}
momoyu {
}
}
3.定义buildTypes
在这里我们把需要接入不同sdk的平台,都单独定义一个buildType,同时设置他们buildConfigField的值
例如
buildTypes {
release {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
}
m4399ad {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "boolean", "M4399_AD", "true"
buildConfigField "boolean", "TT_AD", "false"
}
m233ad {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "boolean", "TT_AD", "false"
buildConfigField "boolean", "M233_AD", "true"
}
vivoad {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "boolean", "TT_AD", "false"
buildConfigField "boolean", "VIVO_AD", "true"
}
}
4.过滤掉无效的包体
在打包时 productFlavors*buildTypes是打出的所有包,注意是相乘的关系,所以有很多包是我们不需要的,需要 过滤掉
在 variantFilter中variant.buildType.name是包本的buildType, variant.getFlavors().get(0).name是包体的flavor,通过这两个值可以将我们不想要的包体过滤掉。
variant.setIgnore(true)
variantFilter { variant ->
if(variant.getFlavors().get(0).name.contains('m233') || variant.getFlavors().get(0).name.contains('m4399') || variant.getFlavors().get(0).name.contains('vivo')){
if (variant.buildType.name.equals('debug')) {
variant.setIgnore(true);
}
if ( variant.buildType.name.equals('release') ) {
variant.setIgnore(true);
}
}
if (variant.buildType.name.equals('m4399ad') && !variant.getFlavors().get(0).name.contains('m4399')) {
variant.setIgnore(true);
}
if (variant.buildType.name.equals('m233ad') && !variant.getFlavors().get(0).name.contains('m233')) {
variant.setIgnore(true);
}
if (variant.buildType.name.equals('vivoad') && !variant.getFlavors().get(0).name.contains('vivo')) {
variant.setIgnore(true);
}
}
5.依赖jar和aar
那么如果在不同的平台下依赖不同的sdk呢
需要用到两种依赖方式 CompileOnly和implementation
CompileOnly顾名思义,只在编译期生效比如我们在a平台时,b平台相关的sdk我们是用不到的,但是如果我们不依赖又会报错,这个时候我们可以用CompileOnly,只在编译时生效,构建好的包体是找不到CompileOnly的sdk的
implementation是正常的依赖,在编译期和运行时都会生效。
可以在CompileOnly或者implementation前面加上buildType
例如
debugImplementation(name: 'open_ad_sdk', ext: 'aar')
releaseImplementation(name: 'open_ad_sdk', ext: 'aar')
m4399adCompileOnly files('libs/ttad.jar')
m233adCompileOnly files('libs/ttad.jar')
vivoadCompileOnly files('libs/ttad.jar')
注意aar的这种依赖我们需要把arr解压出来,把里面的jar放到我们的libs文件夹中
6.不同平台的资源不同时的处理
我们可以src下面建各个flavor或者buildType的文件夹,用来替换该平台的一些文件
注意文件里面的路径必须与main文件下相同。
如果不同平台的AndroidManifest.xml配置不同也可以在该文件下修改。
例如穿山甲广告配置在其它平台不需要,配置上又会崩溃。
这时我们可以不需要穿山甲配置的平台下remove该配置
<provider
tools:node="remove"
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<provider
tools:node="remove"
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />
再比如在a平台下横屏,在b平台下竖屏,同样可以修改配置
<activity
tools:node="replace"
android:name=".ui.activity.SplashActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
必须支持,感谢分享
mark,虽然不会用
mark~~~~~~~~
大佬,能不能发个完整的demo看看
求大佬发个demo
mark一下
implementation ‘com.longsh:OptionFrame:1.0.0’ 这种加载远程包的 怎么做多平台??
mark~~~