জাভাতে গ্রেডলে কোনও পরিবর্তনশীল ঘোষণা করা সম্ভব?


417

জাভাতে গ্রেডলে কোনও পরিবর্তনশীল ঘোষণা করা সম্ভব? মূলত আমি বিল্ড.gradle এ কিছু ভার ঘোষণা করতে চাই এবং তারপরে এটি নির্ধারিত সময়ে পাওয়া (স্পষ্টতই)। ঠিক সি / সি ++ তে প্রি-প্রসেসর ম্যাক্রোগুলির মতো ...

ঘোষণার উদাহরণটি এরকম কিছু হতে পারে ...:

android {
    debug {
        A_VAR_RETRIEVABLE_IN_JAVA = 42
    }
    release {
        A_VAR_RETRIEVABLE_IN_JAVA = 42+52
    }
}

এরকম কিছু করার উপায় আছে?

উত্তর:


796

জাভা কনস্ট্যান্ট তৈরি করুন

android {
    buildTypes {
        debug {
            buildConfigField "int", "FOO", "42"
            buildConfigField "String", "FOO_STRING", "\"foo\""
            buildConfigField "boolean", "LOG", "true"
        }

        release {
            buildConfigField "int", "FOO", "52"
            buildConfigField "String", "FOO_STRING", "\"bar\""
            buildConfigField "boolean", "LOG", "false"
        }
    }
}

আপনি এগুলি দিয়ে অ্যাক্সেস করতে পারেন BuildConfig.FOO

অ্যান্ড্রয়েড সংস্থান তৈরি করুন

android {
    buildTypes {
        debug{
            resValue "string", "app_name", "My App Name Debug"
        }
        release {
            resValue "string", "app_name", "My App Name"
        }
    }
}

আপনি এগুলি সাথে @string/app_nameবা স্বাভাবিক পদ্ধতিতে অ্যাক্সেস করতে পারেনR.string.app_name


4
না, তবে আপনি পাশাপাশি সংস্থান তৈরি করতে পারেন। আমি সহ আমার উত্তর আপডেট করেছি।
rciovati

2
অান্তরিক ধন্যবাদ. আমি আবিষ্কার করেছি যে কিছু ভালভাবে আপনি ডিবাগ এবং রিলিজ বিল্ড জন্য বিকল্প ডিরেক্টরি নির্দিষ্ট করতে পারে। ইন <project>/src/, আপনি যদি ফাইল debug/res/values/strings.xmlএবং অন্য একটি ফাইল তৈরি করেন তবে আপনি release/res/values/strings.xmlডিবাগের জন্য সংস্থান নির্ধারণ করতে পারেন এবং রিলিজ বিল্ডগুলিও কিছুটা পরিষ্কার উপায়ে তৈরি করতে পারেন।
elimirks

6
@ আরসিওওবাতি কি androidপ্লাগইন ছাড়া এটি অর্জন সম্ভব ? অর্থাৎ শুধু ব্যবহার করছেন apply plugin java? ধন্যবাদ!
জেনিচিমারো 26'14

2
আমি কীভাবে বিভিন্ন বিল্ড ফ্লেভার এবং বিল্ড টাইপের জন্য কনস্ট্যান্ট তৈরি করতে পারি?
জাকব এরিকসন

3
বর্তমান বছর হিসাবে কোনও একটি ক্ষেত্র সেট করা এবং এটির কাছে পৌঁছানো কি বিল্ড প্রকারটি বেছে নেওয়া উচিত নয় (রিলিজ, ডিবাগ, ...)?
অ্যান্ড্রয়েড বিকাশকারী

102

অ্যান্ড্রয়েড অ্যাপ্লিকেশনে একটি অ্যাপি অ্যাপ্লিকেশন কী (জাভা এবং এক্সএমএল) ব্যবহারের উদাহরণ

gradle.properties

AppKey="XXXX-XXXX"

build.gradle

buildTypes {
//...
    buildTypes.each {
        it.buildConfigField 'String', 'APP_KEY_1', AppKey
        it.resValue 'string', 'APP_KEY_2', AppKey
    }
}

জাভা কোড ব্যবহার করুন

Log.d("UserActivity", "onCreate, APP_KEY: " + getString(R.string.APP_KEY_2));

BuildConfig.APP_KEY_1

এক্সএমএল কোড ব্যবহার

<data android:scheme="@string/APP_KEY_2" />

1
যদি আমি যুক্ত করতে পারি তবে এই পরিবর্তনশীলটি রানটাইমটিতেও পাস করা যেতে পারে। বিভিন্ন কনফিগারেশন সহ পরীক্ষা চলাকালীন বেশিরভাগ দরকারী। ব্যবহার./gradlew -PAppKey="1234" testdebug
জাসওয়ানথ মনিগুন্ডন

1
প্রতিটি বিল্ড টাইপ জন্য একই সম্পত্তি ডিক্লেয়ার আপনি ব্যবহার করতে পারেন defaultConfigহিসাবে ভাল ব্লক: stackoverflow.com/a/51521146/321354
rciovati

আপনার কাছে কি এক্সএমএল অংশের কার্যকারী উদাহরণ রয়েছে? গিথুব সংগ্রহস্থল বা গিস্টে। এটি আমার পক্ষে কাজ করছে না, আমি উল্লেখ করতে পারি না@string/APP_KEY_2
ভোগদেব

32

বিল্ড.gradle এ সেট করা সিস্টেম বৈশিষ্ট্যগুলি ব্যবহার করার উদাহরণ, জাভা অ্যাপ্লিকেশন থেকে পড়া (মন্তব্যে প্রশ্ন থেকে অনুসরণ করে):

মূলত, ব্যবহার testমধ্যে কাজের build.gradle, পরীক্ষা টাস্ক পদ্ধতি সঙ্গে systemPropertyএকটি সিস্টেম সম্পত্তি যে রানটাইম এ পাস করুন:

apply plugin: 'java'
group = 'example'
version = '0.0.1-SNAPSHOT'

repositories {
    mavenCentral()
    // mavenLocal()
    // maven { url 'http://localhost/nexus/content/groups/public'; }
}

dependencies {
    testCompile 'junit:junit:4.8.2'
    compile 'ch.qos.logback:logback-classic:1.1.2'
}

test {
  logger.info '==test=='
  systemProperty 'MY-VAR1', 'VALUE-TEST'
}

এবং এখানে বাকি নমুনা কোডটি (যা আপনি সম্ভবত অনুমান করতে পারেন, তবে যে কোনও উপায়ে এখানে অন্তর্ভুক্ত করা হয়েছে): এটি একটি সিস্টেম সম্পত্তি পায় MY-VAR1যা রান-টাইমে সেট করা হবে বলে প্রত্যাশিত VALUE-TEST:

package example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  static final Logger log=LoggerFactory.getLogger(HelloWorld.class);
  public static void main(String args[]) {
    log.info("entering main...");
    final String val = System.getProperty("MY-VAR1", "UNSET (MAIN)");
    System.out.println("(main.out) hello, world: " + val);
    log.info("main.log) MY-VAR1=" + val);
  }
}

টেস্টকেস: যদি MY-VARসেট না করা থাকে তবে পরীক্ষাটি ব্যর্থ হওয়া উচিত:

package example;
...
public class HelloWorldTest {
    static final Logger log=LoggerFactory.getLogger(HelloWorldTest.class);
    @Test public void testEnv() {
        HelloWorld.main(new String[]{});
        final String val = System.getProperty("MY-VAR1", "UNSET (TEST)");
        System.out.println("(test.out) var1=" + val);
        log.info("(test.log) MY-VAR1=" + val);
        assertEquals("env MY-VAR1 set.", "VALUE-TEST", val);
    }
}

চালান (দ্রষ্টব্য: পরীক্ষা পাস হচ্ছে):

$ gradle cleanTest test
:cleanTest
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test

BUILD SUCCESSFUL

আমি দেখতে পেয়েছি যে জটিল অংশটি আসলে গ্রেড থেকে আউটপুট পাচ্ছে ... সুতরাং, লগিং এখানে কনফিগার করা হয়েছে (slf4j + লগব্যাক), এবং লগ ফাইল ফলাফলগুলি দেখায় (বিকল্পভাবে, চালান gradle --info cleanTest test; এমন বৈশিষ্ট্যও রয়েছে যা স্টাডআউট হয় কনসোল, তবে, আপনি জানেন, কেন):

$ cat app.log
INFO Test worker example.HelloWorld - entering main...
INFO Test worker example.HelloWorld - main.log) MY-VAR1=VALUE-TEST
INFO Test worker example.HelloWorldTest - (test.log) MY-VAR1=VALUE-TEST

যদি আপনি " systemProperty..." মন্তব্য করেন (যা, বিটিডব্লিউ, কেবল কোনও testটাস্কে কাজ করে), তবে:

example.HelloWorldTest > testEnv FAILED
    org.junit.ComparisonFailure at HelloWorldTest.java:14

সম্পূর্ণতার জন্য, এখানে লগব্যাক কনফিগারেশন ( src/test/resources/logback-test.xml):

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d %p %t %c - %m%n</pattern>
        </layout>
 </appender>
 <root level="info">
     <appender-ref ref="FILE"/>
</root>
</configuration> 

নথি পত্র:

  • build.gradle
  • src/main/java/example/HelloWorld.java
  • src/test/java/example/HelloWorldTest.java
  • src/test/resources/logback-test.xml

দ্রষ্টব্য যে এটি গৃহীত উত্তরের মন্তব্যে সরাসরি প্রতিক্রিয়া, সুতরাং এটি মূল প্রশ্ন থেকে কিছুটা বিচ্যুত হয়।
মাইকেল 25

2
আমি কি কোনওভাবে version = '0.0.1-SNAPSHOT'জাভা কোডের মাধ্যমে পেতে পারি ?
Nom1fan

সিস্টেমপ্রোপার্টি কেবল গ্রেড টেস্ট টাস্কে পাওয়া যায় :(। লাইব্রেরির জাভা কোডে গ্রেড ভেরিয়েবলের মান থাকার জন্য অন্য যে কোনও উপায়ে জানেন?
স্টোইচো আন্দ্রিভ

systemPropertyসত্যই কেবল পরীক্ষার জন্য বোধগম্য হয়, তাই আমি দেখি যে তারা কেন এটি করেছে (এটি কোনও তদারকি নয়) তবে একই সাথে, আমি এমন জিনিসগুলির জন্য গ্রেডও ব্যবহার করার চেষ্টা করেছি (অ্যাপ্লিকেশন ডিএসএলের মতো) ) তাই আমি সনাক্ত করতে পারি। বিকল্প হিসাবে, আমি কেবল একটি সম্পত্তি ফাইল (বা কনফিগারেশন পরিষেবা ইত্যাদি) থেকে সম্পত্তি লোড করার পরামর্শ দেব, কারণ এটি যদি "পরীক্ষার" মোডে না থাকে, তবে এটি "উত্পাদন" মোডে এবং অ্যাপ্লিকেশন যুক্তির প্রয়োজন। (এটি যাইহোক, তত্ত্ব।)
মাইকেল 18

14

আপনি বিল্ড চলাকালীন সিস্টেম এনভায়রনমেন্ট ভেরিয়েবলের মাধ্যমে বিল্ড কনফিগারেশন ফিল্ডকে ওভারডেবল তৈরি করতে পারেন:

ফলব্যাকটি ডেভলপ করার সময় ব্যবহৃত হয় তবে জেনকিনস বা অন্য কোনও সরঞ্জামে বিল্ডটি চালানোর সময় আপনি চলকটি ওভাররাইড করতে পারেন।

আপনার অ্যাপ্লিকেশন build.gradle এ :

buildTypes {
        def serverUrl =  '\"' + (System.getenv("SERVER_URL")?: "http://default.fallback.url.com")+'\"'
        debug{
            buildConfigField "String", "SERVER_URL", serverUrl
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "String", "SERVER_URL", serverUrl
        }
    } 

ভেরিয়েবল হিসাবে উপলব্ধ হবে BuildConfig.SERVER_URL


1
এই উত্তরের জন্য আপনাকে ধন্যবাদ! আমি একটি অ্যান্ড্রয়েড। জাভা ফাইলের মধ্যে থেকে পরিবেশের পরিবর্তনশীলটি কীভাবে দৃশ্যমান হয় সে সম্পর্কে কীভাবে কাজ করার চেষ্টা করছি এবং এটি দুর্দান্ত কাজ করেছে!
ওয়েইন পাইকারস্কি

আপনি যদি বুলিয়ান ভেরিয়েবলটি সংজ্ঞায়িত করতে চান তবে আপনার বিল্ডকনফিগফিল্ড "বুলিয়ান", "সিআই_বিল্ড", "$ {আইসসি}" বা বিল্ডকনফিগফিল্ড "বুলিয়ান", "সিআই_বিল্ড", "বুলিয়ান.পার্সবুলিয়ান (" + '"+ ইসি ব্যবহার করা উচিত "'+") "যদি আপনি লিন্ট চেকগুলি ( স্ট্যাকওভারফ্লো.com / প্রশ্নগুলি / 29889098/… ) এড়াতে চান
অ্যান্ড্রয়েড_দেব

5

rciovati এর উত্তর সম্পূর্ণরূপে সঠিক আমি কেবল একটি আরও টিডবিট যুক্ত করতে চেয়েছিলাম যা আপনি আপনার বিল্ড.gradle এর ডিফল্ট কনফিগার অংশের মধ্যে প্রতিটি বিল্ড ধরণের জন্য ভেরিয়েবল তৈরি করতে পারেন। এটি দেখতে এরকম হবে:

android {
    defaultConfig {
        buildConfigField "String", "APP_NAME", "\"APP_NAME\""
    }
}

এটি আপনাকে এর মাধ্যমে অ্যাক্সেসের অনুমতি দেবে

BuildConfig.App_NAME

আপনি যদি একটি সাধারণ কনফিগার করতে চান তবে কেবল এই দৃশ্যের একটি নোট তৈরি করতে চেয়েছিলেন।


3

আমি এই কোডটি ব্যবহার করছি এবং খুব সূক্ষ্মভাবে কাজ করছি।

def baseUrl = '\"http://patelwala.com/myapi/"'
def googleServerKey = '\"87171841097-opu71rk2ps35ibv96ud57g3ktto6ioio.apps.googleusercontent.com"'
android {
  buildTypes {
  release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        buildConfigField 'String', 'BASE_URL', baseUrl
        buildConfigField 'String', 'web_client_id', googleServerKey
    }
    releasedebug {
        initWith debug
        buildConfigField 'String', 'BASE_URL', baseUrl
        buildConfigField 'String', 'web_client_id' ,googleServerKey
    }
    debug {

        buildConfigField 'String', 'BASE_URL', baseUrl
        buildConfigField 'String', 'web_client_id', googleServerKey
    }
 }
}

}


আপনার কাজের সমাধানের ফলে আপনি কী পরিবর্তন করেছেন এবং এর কী প্রভাব ফেলে তা যদি আপনি নির্দিষ্ট করেন তবে এটি দুর্দান্ত হবে।
ব্যাজি

2

আপনি বিল্ডকনফিগফিল্ডে ফাংশনের স্ট্রিং ফলাফল কীভাবে সন্নিবেশ করতে পারেন

মানব-পঠনযোগ্য ফর্ম্যাট সেটে বিল্ড ডেটের উদাহরণ এখানে রয়েছে:

def getDate() {
    return new SimpleDateFormat("dd MMMM yyyy", new Locale("ru")).format(new Date())
}

def buildDate = getDate()

defaultConfig {
    buildConfigField "String", "BUILD_DATE", "\"$buildDate\""
}


0

উপরের কোনও উত্তরই আমাকে কোনও নির্দেশিকা দেয় নি তাই গ্রোভি পদ্ধতি সম্পর্কে শিখতে আমাকে দুই ঘন্টা ব্যয় করতে হয়েছিল।

আমি একটি উত্পাদন, স্যান্ডবক্স এবং স্থানীয় পরিবেশের বিরুদ্ধে যেতে সক্ষম হতে চেয়েছিলেন। কারণ আমি অলস, আমি কেবল এক জায়গায় ইউআরএল পরিবর্তন করতে চেয়েছিলাম। আমি এখানে যা এলাম:

 flavorDimensions 'environment'
    productFlavors {
        production {
            def SERVER_HOST = "evil-company.com"
            buildConfigField 'String', 'API_HOST', "\"${SERVER_HOST}\""
            buildConfigField 'String', 'API_URL', "\"https://${SERVER_HOST}/api/v1/\""
            buildConfigField 'String', 'WEB_URL', "\"https://${SERVER_HOST}/\""
            dimension 'environment'
        }
        rickard {
            def LOCAL_HOST = "192.168.1.107"
            buildConfigField 'String', 'API_HOST', "\"${LOCAL_HOST}\""
            buildConfigField 'String', 'API_URL', "\"https://${LOCAL_HOST}/api/v1/\""
            buildConfigField 'String', 'WEB_URL', "\"https://${LOCAL_HOST}/\""
            applicationIdSuffix ".dev"
        }
    }

বিকল্প সিনট্যাক্স, কারণ আপনি কেবল ${variable}গ্রোভি পদ্ধতিতে ডাবল উদ্ধৃতি দিয়ে ব্যবহার করতে পারেন ।

    rickard {
        def LOCAL_HOST = "192.168.1.107"
        buildConfigField 'String', 'API_HOST', '"' + LOCAL_HOST + '"'
        buildConfigField 'String', 'API_URL', '"https://' + LOCAL_HOST + '/api/v1/"'
        buildConfigField 'String', 'WEB_URL', '"https://' + LOCAL_HOST + '"'
        applicationIdSuffix ".dev"
    }

আমার পক্ষে যে বিষয়টি উপলব্ধি করা শক্ত ছিল তা হল স্ট্রিংগুলিকে উদ্ধৃতি দ্বারা ঘিরে থাকা স্ট্রিং হিসাবে ঘোষণা করা দরকার। এই বিধিনিষেধের কারণে আমি API_HOSTসরাসরি রেফারেন্স ব্যবহার করতে পারি না , যা আমি প্রথম স্থানে করতে চেয়েছিলাম।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.