android多平台打包方案

对于不开发android的兄弟可能gradle的很多功能不会用,这里给出一个我自己用的多平台打包方案

3赞

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的文件夹,用来替换该平台的一些文件QQ20211225-164427
注意文件里面的路径必须与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>
3赞

我的 build.gradle https://test-1252163606.cos.ap-chengdu.myqcloud.com/build.gradle

必须支持,感谢分享

mark,虽然不会用

mark~~~~~~~~

大佬,能不能发个完整的demo看看

求大佬发个demo

mark一下

implementation ‘com.longsh:OptionFrame:1.0.0’ 这种加载远程包的 怎么做多平台??

mark~~~