Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

Combine 2 Similar Projects With Android Build Variant

We do have a 2 similar projects for an app. First one is for my country and second one is for EU. They are %90 same may be more. We do want to merge this two project into one and switch between them with build variants. Is that possible ? If it is, could you tell me how can i do it ?

Main Project

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setImageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
        } else {
            ImageView.setImageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

EU Project

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setImageResource(R.drawable.EuInactive);
            ImageView.setContentDescription(getString(R.string.EUpassive));
            presenter.sendCommand();
            isEnabled = false;
        } else {
            ImageView.setImageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.EUactive));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

For example some drawable are different on EU Project

- Or -

Main Project

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setImageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
            DoSomething();
        } else {
            ImageView.setImageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

Eu Project

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setImageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
            DoSomethingElse();
        } else {
            ImageView.setImageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

In this example we did added different line everything else is similar.

There nearly a thousand of this kind of differences and nearly five hundreds of excatly same classes and two hunderds of new classes.

In conclusion, how can i manage these two projects with build variants in one project

Edit 2 : I've tried these steps.

1- implement dimensions 2- implement flavor 3- created res,asset,java files for eu project 4- created sourceSet in gradle for eu project

for now build variant looks like this mainDevDebug,EuDevDebug,... etc main...... ones works fine but i had an error for Eu..... ones

Error message while rebuilding or runing app

Could not determine the dependencies of task ':app:compileEuTestDebugJavaWithJavac'.
> Could not resolve all task dependencies for configuration ':app:EuTestDebugCompileClasspath'.
   > Could not resolve project :com.xx.core.main.core.
     Required by:
         project :app
      > No matching configuration of project :com.xx.core.main.core was found. The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'project' with value 'Eu', attribute 'default' with value 'Test', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
          - None of the consumable configurations have attributes.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

From the code you've posted and from the comments, I believe you'd be able to achieve what you're looking for with product flavors read more here.

in your APP-level build.gradle, you'd do something like this :

android {  
    flavorDimensions 'default'
    productFlavors {

        foo{
            dimension 'default'
        }

        bar{
            dimension 'default'
        }

    }
}

this will define two different product flavors for you, specifically foo and bar. after doing a gradle sync, you'll see you now have these available as build variants.

enter image description here

next what you'll do, is create a folder structure similar to this: enter image description here

creating a folder for bar, a folder for foo and leaving the folder for main, with the package signature inside each folder matching what your main structure is using. if you have image resources which will be different, make sure they're in appropriate folders here. If you're struggling to create a specific type of file/folder, I'd suggest just copying it over.

everything inside main will be used in BOTH types of apps, so all the logic which is the same, will remain there. everything which can be different will reside in the folders for bar and for foo. In my case, a simple class called Example:

class Example {

    fun giveValue(context: Context): String {
        return context.getString(R.string.value)
    }
}

the implementation for both of these classes are exactly the same in both folders, although yours could (and will) be entirely different.

You'll also see I have added strings.xml into my product flavors (in your case, perhaps this would be image resources as well), I've added the following string:

<resources>
    <string name="value">from bar</string>
</resources>

into the strings.xml found under the bar directory and

<resources>
    <string name="value">from foo</string>
</resources>

into the strings.xml found under the foo directory

my Example class therefore just returns whatever this value is based on the build variant

and that's it.

inside my main activity:

  val result = Example().giveValue(this)
        Log.v("testing", result) 

so, depending on the build variant i'm using (either fooDebug or barDebug) the output will be different.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...