Android Studio 构建风格 - 如何在不同风格中拥有相同的源文件

Android Studio build flavors - How to have same source files in diverse flavors

我需要在 android studio 中为应用程序创建演示版本。在我的应用级别 gradle 文件中,我创建了另一种名为 demo 的风格,当然还有默认风格。它看起来像这样:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.uen229.myapplication"
        minSdkVersion 17
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        demo {
            applicationId "com.buildsystemexample.app.demo"
            versionName "1.0-demo"
        }
        full {
            applicationId "com.buildsystemexample.app.full"
            versionName "1.0-full"
        }
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}

这是我的项目结构的图像,我在其中创建了一个演示风格目录:

现在进入正题。我有两个 classes 叫做 Hello.java。两者都有各自的口味并打印不同的东西。我现在将向您展示这两个文件:

import android.util.Log;

/** this is from demo flavor directory**/

public class Hello {

    Hello(){

        Log.v("","hello from demo");
    }

    public String getName();
        return "im from demo";

    };

}

这是另一个你好:

package com.example.uen229.myapplication;

import android.util.Log;


/** this is from full or main flavor directory**/
public class Hello {


    Hello(){

        Log.v("", "hello from main");
    }

    public String getName(){

        return "im from main";

    };
}

注意第一个 hello.java 没有包,即使我有包 IDE 也无法编译。看看这张照片:

现在最后让我们看一下 mainActivity.java,看看当我切换构建变体时,它只会为 "im from main" 干杯,但如果我使用 demoDebug,我需要它来打印“我来自演示”构建变体。如果我将构建变体切换为 demoDebug,它仍会打印 "im from main"。有人能帮忙吗:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Hello h = new Hello();
        Toast.makeText(this, h.getName(), Toast.LENGTH_LONG).show();

    }
}

更新

来自 Whosebug 它说:

If you want to have a different version of the same class in the two flavor you'll need to create it in both flavors.

src/flavor1/java/com/foo/A.java

src/flavor2/java/com/foo/A.java

And then your code in src/main/java can do:

import com.foo.A

depending on the flavor selected, the right version of com.foo.A is used.

这就是我想用 Hello class

完成的

我认为你不能在主口味和你的其他口味中使用相同的 class。您应该只创建另一种风味,然后将 Hello class 从主要风味移至该新风味。此规则仅适用于 .java 文件。我的意思是你可以有一个主要风格的 xml 文件和自定义风格的另一个版本,但你不能用 java 文件做到这一点。

here 很有用 link 有进一步的解释。

我建议创建 3 个源集:

  • main - 包含常见的 类
  • demo - 包含特定的演示 类
  • pro - 包含 类 专业版

并使用以下方式声明它们:

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src/main/java']
        res.srcDirs = ['src/main/res']
        assets.srcDirs = ['src/main/assets']
    }
    pro {
        manifest.srcFile 'src/pro/AndroidManifestPro.xml'
        java.srcDirs = ['src/main/java', 'src/pro/java']
    }
    demo {
        manifest.srcFile 'src/oldlite/AndroidManifestDemo.xml'
        java.srcDirs = ['src/main/java', 'src/demo/java']        
    }
}

P.S。不太确定 java.srcDirs 内容的语法 - 请仔细检查自己

我能够覆盖 classes,但关键是不要将 class 包含在我的主文件夹中。

因此 fullDebug(即主文件夹)构建变体将永远不会 运行。总是 运行 一个风味而不是主文件夹。主文件夹将仅用于在其中保存常用内容。

在我的例子中,我有一个美国和另一个国家的演示(演示和 demo_us),我需要两种口味。我将始终为两者中的任何一个构建,而不会构建 main。

从图中可以看出,我将所有包名称都设置为相同:如 com.example.******.myapplication。由于它们在 MainActivity 中都具有相同的包名称,您只需使用该包名称导入 Hello.java,它将在构建时选择正确的变体。

对于资源来说,它看起来是不同的,它会自然地覆盖,但是 java class 文件必须这样做。