Gradle টিপস এবং রেসিপি

Gradle এবং Gradle-এর জন্য Android প্লাগইন আপনার Android অ্যাপ বা লাইব্রেরি কম্পাইল, তৈরি এবং প্যাকেজ করার একটি নমনীয় উপায় প্রদান করে। এই পৃষ্ঠাটি আপনাকে প্রতিটি বিল্ড থেকে সর্বাধিক পেতে সাহায্য করার জন্য কিছু দরকারী টিপস এবং কনফিগারেশন সংগ্রহ করে৷ আপনি যদি আপনার বিল্ডগুলিকে দ্রুততর করার উপায়গুলি সম্পর্কে জানতে চান তবে আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনি যদি Gradle-এ নতুন হয়ে থাকেন, তাহলে আপনার বিল্ড কনফিগার করুন পড়ে বুনিয়াদি শিখুন। এই পৃষ্ঠায় ব্যবহৃত বৈশিষ্ট্যগুলি সম্পর্কে আরও জানতে আপনি Android প্লাগইনের DSL রেফারেন্স ডকুমেন্টেশনও পরিদর্শন করতে পারেন৷

প্রকল্প এবং উত্স পরিচালনা করুন

আপনার প্রকল্পের মডিউল এবং তাদের উত্সগুলি পরিচালনা করার জন্য এখানে কিছু কনফিগারেশন রয়েছে৷ প্রকল্প এবং মডিউল তৈরি এবং পরিচালনার বিষয়ে আরও জানতে, প্রকল্প ওভারভিউ পড়ুন।

ডিফল্ট সোর্স সেট কনফিগারেশন পরিবর্তন করুন

আপনি মডিউল-স্তরের build.gradle ফাইলে sourceSets ব্লক ব্যবহার করতে পারেন যেখানে Gradle একটি সোর্স সেটের প্রতিটি উপাদানের জন্য ফাইল সংগ্রহ করতে দেখায়।

গ্রোভি

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.srcDirs = ['other/res1', 'other/res2']

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    getByName("main") {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.setSrcDirs("other/java")

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.setSrcDirs("other/res1", "other/res2")

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile("other/AndroidManifest.xml")
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
    }
  }
}
...

লাইব্রেরি এবং নির্ভরতা পরিচালনা করুন

Gradle নির্ভরতাগুলি পরিচালনা করার জন্য একটি শক্তিশালী প্রক্রিয়া প্রদান করে, সেগুলি দূরবর্তী লাইব্রেরি বা স্থানীয় লাইব্রেরি মডিউল হোক না কেন।

নির্ভরতা কনফিগারেশনের সাথে নির্দিষ্ট বিল্ডগুলি লক্ষ্য করুন

আপনি যদি শুধুমাত্র একটি নির্দিষ্ট বিল্ড ভেরিয়েন্ট সোর্স সেট বা টেস্টিং সোর্স সেটের জন্য নির্ভরতা চান, তাহলে ডিপেন্ডেন্সি কনফিগারেশনের নামটি ক্যাপিটালাইজ করুন এবং বিল্ড ভ্যারিয়েন্ট বা টেস্টিং সোর্স সেটের নামের সাথে এটিকে প্রিফিক্স করুন।

গ্রোভি

android {...}

// Creates Gradle dependency configurations to use in the dependencies block.
configurations {
  // For variants that combine a product flavor and build type, you need to
  // intitialize a placeholder for its dependency configuration.
  freeDebugRuntimeOnly{}
  ...
}

dependencies {
    // Adds an implementation dependency only to the "free" product flavor.
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

কোটলিন

android {...}

dependencies {
    // Use ""() notation for custom flavors and build types
    // Adds an implementation dependency only to the "free" product flavor.
    "freeImplementation"("com.google.firebase:firebase-ads:21.5.1")
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    "freeDebugRuntimeOnly"(fileTree("dir" to "libs", "include" to "*.jar"))
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}

আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করুন

Gradle এবং Android প্লাগইন আপনাকে বিল্ড ভেরিয়েন্ট কনফিগার করে একটি একক মডিউল থেকে আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে দেয়।

ডায়নামিক সংস্করণ কোড কনফিগার করুন

ডিফল্টরূপে, যখন Gradle আপনার প্রকল্পের জন্য APK তৈরি করে, তখন প্রতিটি APK-এর একই সংস্করণের তথ্য থাকে, যেমনটি মডিউল-স্তরের build.gradle ফাইলে উল্লেখ করা হয়েছে। যেহেতু Google Play Store একই অ্যাপের জন্য একাধিক APK মঞ্জুরি দেয় না যার সকলের কাছে একই সংস্করণের তথ্য রয়েছে, তাই আপনি Play Store এ আপলোড করার আগে প্রতিটি APK এর নিজস্ব অনন্য সংস্করণকোড আছে তা নিশ্চিত করতে হবে।

আপনি কাস্টম বিল্ড লজিক দিয়ে এটি করতে পারেন যা বিল্ড টাইমে প্রতিটি APK কে একটি ভিন্ন সংস্করণ কোড বরাদ্দ করে। উদাহরণস্বরূপ, প্রতিটি ABI-এর জন্য পৃথক APK তৈরি করার সময়, স্বয়ংক্রিয় APK সংস্করণ দেখতে এরকম কিছু দেখায়:

গ্রোভি

android {
  ...
  defaultConfig {
    ...
    versionCode 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3]

// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['hdpi': 1, 'xhdpi': 2, 'xxhdpi': 3, 'xxxhdpi': 4]

import com.android.build.OutputFile

// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->

  // Assigns a different version code for each output APK
  // other than the universal APK.
  variant.outputs.each { output ->

    // Stores the value of ext.abiCodes that is associated with the ABI for this variant.
    def baseAbiVersionCode =
            // Determines the ABI for this variant and returns the mapped value.
            project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))

    // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
    // the following code does not override the version code for universal APKs.
    // However, because we want universal APKs to have the lowest version code,
    // this outcome is desirable.
    if (baseAbiVersionCode != null) {

      // Assigns the new version code to versionCodeOverride, which changes the version code
      // for only the output APK, not for the variant itself. Skipping this step simply
      // causes Gradle to use the value of variant.versionCode for the APK.
      output.versionCodeOverride =
              baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}

কোটলিন

android {
  ...
  defaultConfig {
    ...
    versionCode = 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
val abiCodes = mapOf("armeabi-v7a" to 1, "mips" to 2, "x86" to 3)

// For per-density APKs, create a similar map like this:
// val densityCodes = mapOf("hdpi" to 1, "xhdpi" to 2, "xxhdpi" to 3, "xxxhdpi" to 4)

import com.android.build.api.variant.FilterConfiguration.FilterType.*

// For each APK output variant, override versionCode with a combination of
// abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
androidComponents {
    onVariants { variant ->

        // Assigns a different version code for each output APK
        // other than the universal APK.
        variant.outputs.forEach { output ->
            val name = output.filters.find { it.filterType == ABI }?.identifier

            // Stores the value of abiCodes that is associated with the ABI for this variant.
            val baseAbiCode = abiCodes[name]
            // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
            // the following code does not override the version code for universal APKs.
            // However, because we want universal APKs to have the lowest version code,
            // this outcome is desirable.
            if (baseAbiCode != null) {
                // Assigns the new version code to output.versionCode, which changes the version code
                // for only the output APK, not for the variant itself.
                output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0))
            }
        }
    }
}

একাধিক পণ্যের স্বাদ একত্রিত করুন

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

নিম্নলিখিত কোড নমুনাটি "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদগুলিকে গোষ্ঠীভুক্ত করতে একটি "মোড" স্বাদের মাত্রা তৈরি করতে flavorDimensions বৈশিষ্ট্য ব্যবহার করে এবং API স্তরের উপর ভিত্তি করে পণ্যের স্বাদ কনফিগারেশনের গ্রুপ করার জন্য একটি "এপিআই" ফ্লেভারের মাত্রা ব্যবহার করে। Gradle তারপর "মোড" মাত্রা থেকে "api" মাত্রার সাথে পণ্যের স্বাদকে একত্রিত করে।

গ্রোভি

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion '24'
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion '23'
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion '21'
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdkVersion(24)
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode = 30000 + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdkVersion(23)
      versionCode = 20000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdkVersion(21)
      versionCode = 10000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

ফিল্টার বৈকল্পিক

আপনি মডিউলের build.gradle ফাইলে variantFilter ব্লক ব্যবহার করে বিল্ড ভেরিয়েন্টগুলি ফিল্টার করতে পারেন যা আপনি চান না। নিম্নলিখিত নমুনা কোডটি গ্র্যাডলকে বলে যে "মিনএপি21" এবং "ডেমো" পণ্যের স্বাদগুলিকে একত্রিত করে এমন কোনও রূপ তৈরি না করতে:

গ্রোভি

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enabled = false
        }
    }
}
...

আপনার অ্যাপ পরীক্ষা করুন

স্থানীয় এবং সমন্বিত ইউনিট পরীক্ষা চালানোর বিষয়ে আরও জানতে, আপনার অ্যাপ পরীক্ষা করুন পড়ুন।

লিন্ট বিকল্পগুলি কনফিগার করুন

আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে lintOptions ব্লক ব্যবহার করে নির্দিষ্ট লিন্ট বিকল্পগুলি কনফিগার করতে পারেন। আপনার অ্যান্ড্রয়েড প্রকল্পের জন্য লিন্ট ব্যবহার সম্পর্কে আরও জানতে, লিন্টের সাথে আপনার কোড উন্নত করুন পড়ুন।

গ্রোভি

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable 'TypographyFractions','TypographyQuotes'
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly 'NewApi', 'InlinedApi'
        // If set to true, turns off analysis progress reporting by lint.
        quiet true
        // if set to true (default), stops the build if errors are found.
        abortOnError false
        // if true, only report errors.
        ignoreWarnings true
    }
}
...

কোটলিন

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable("TypographyFractions")
        disable("TypographyQuotes")
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable("RtlHardcoded")
        enable("RtlCompat")
        enable("RtlEnabled")
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly("NewApi", "InlinedApi")
        // If set to true, turns off analysis progress reporting by lint.
        quiet = true
        // if set to true (default), stops the build if errors are found.
        abortOnError = false
        // if true, only report errors.
        ignoreWarnings = true
    }
}
...

ইন্সট্রুমেন্টেশন ম্যানিফেস্ট সেটিংস কনফিগার করুন

যখন Gradle আপনার পরীক্ষার APK তৈরি করে, তখন এটি স্বয়ংক্রিয়ভাবে AndroidManifest.xml ফাইল তৈরি করে এবং <instrumentation> নোডের সাথে কনফিগার করে। আপনি এই নোডের জন্য কিছু সেটিংস পরিবর্তন করতে পারেন পরীক্ষা উৎস সেটে অন্য একটি ম্যানিফেস্ট ফাইল তৈরি করে অথবা আপনার মডিউল-স্তরের build.gradle ফাইল কনফিগার করে, যেমনটি নিম্নলিখিত কোড নমুনায় দেখানো হয়েছে।

গ্রোভি

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest true
  }
}
...

কোটলিন

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId = "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner = "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling = true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest = true
  }
}
...

পরীক্ষার বিল্ড টাইপ পরিবর্তন করুন

ডিফল্টরূপে, সমস্ত পরীক্ষা ডিবাগ বিল্ড টাইপের বিরুদ্ধে চলে। আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে testBuildType বৈশিষ্ট্য ব্যবহার করে এটিকে অন্য বিল্ড টাইপে পরিবর্তন করতে পারেন। উদাহরণস্বরূপ, আপনি যদি আপনার "স্টেজিং" বিল্ড টাইপের বিপরীতে আপনার পরীক্ষা চালাতে চান তবে নিম্নলিখিত স্নিপেটে দেখানো ফাইলটি সম্পাদনা করুন।

গ্রোভি

android {
    ...
    testBuildType "staging"
}

কোটলিন

android {
    ...
    testBuildType "staging"
}

Gradle পরীক্ষার বিকল্পগুলি কনফিগার করুন

Gradle কিভাবে আপনার সমস্ত পরীক্ষা চালায় তা পরিবর্তন করে এমন বিকল্পগুলি নির্দিষ্ট করতে, মডিউল-স্তরের build.gradletestOptions ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

কোটলিন

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

শুধুমাত্র স্থানীয় ইউনিট পরীক্ষার জন্য বিকল্পগুলি নির্দিষ্ট করতে, testOptions.unitTests ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

কোটলিন

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

আপনার বিল্ড অপ্টিমাইজ করুন

এই বিভাগটি আপনার সম্পূর্ণ এবং ক্রমবর্ধমান বিল্ডগুলির গতি বাড়ানোর জন্য কিছু কনফিগারেশন সরবরাহ করে। আরও জানতে, আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনার কোড সঙ্কুচিত করুন

অ্যান্ড্রয়েড স্টুডিও R8 ব্যবহার করে, যা আপনার কোড সঙ্কুচিত করতে ProGuard নিয়মের ফাইলগুলি ব্যবহার করে। নতুন প্রকল্পগুলির জন্য, Android স্টুডিও অ্যান্ড্রয়েড SDK-এর tools/proguard/folder থেকে একটি ডিফল্ট সেটিংস ফাইল ( proguard-android.txt ) ব্যবহার করে। আরও বেশি কোড সঙ্কুচিত করার জন্য, একই অবস্থানে থাকা proguard-android-optimize.txt ফাইলটি ব্যবহার করে দেখুন৷

গ্রোভি

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

কোটলিন

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

প্রতিটি বিল্ড ভেরিয়েন্টের জন্য নির্দিষ্ট নিয়ম যোগ করতে, প্রতিটি স্বাদের জন্য অতিরিক্ত proguardFiles বৈশিষ্ট্য কনফিগার করুন। উদাহরণস্বরূপ, নিম্নলিখিত নমুনা "flavor2" তে flavor2-rules.pro যোগ করে। এখন "flavor2" এর রিলিজ সংস্করণটি তিনটি নিয়ম ফাইল ব্যবহার করে কারণ রিলিজ ব্লক থেকেও প্রয়োগ করা হয়।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

আপনার অ্যাপ্লিকেশন প্রকাশ করুন

Google Play-তে আপনার অ্যাপ প্রকাশ করার বিষয়ে আরও জানতে, আপনার অ্যাপ প্রকাশ করুন পড়ুন।

আপনার অ্যাপে সাইন ইন করুন

যদিও অ্যান্ড্রয়েড স্টুডিও UI থেকে রিলিজ বিল্ডের জন্য সাইনিং কনফিগার করার একটি সহজ উপায় প্রদান করে, আপনি আপনার মডিউলের build.gradle ফাইলে signingConfigs ব্লক ম্যানুয়ালি কনফিগার করতে পারেন:

গ্রোভি

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

আপনার প্রকল্প থেকে ব্যক্তিগত স্বাক্ষর তথ্য সরান

ডিফল্টরূপে, সাইনিং কনফিগারেশনগুলি মডিউলের build.gradle ফাইলে প্লেইন টেক্সটে রেকর্ড করা হয়। আপনি যদি একটি দল বা একটি ওপেন-সোর্স প্রকল্পের সাথে কাজ করেন, তাহলে আপনি এই সংবেদনশীল তথ্যটিকে বিল্ড ফাইলের বাইরে নিয়ে যেতে পারেন।

  1. আপনার প্রকল্পের রুট ডিরেক্টরিতে keystore.properties নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত তথ্য অন্তর্ভুক্ত করুন:
    storePassword=myStorePassword
    keyPassword=myKeyPassword
    keyAlias=myKeyAlias
    storeFile=myStoreFileLocation
    
  2. আপনার build.gradle ফাইলে, keystore.properties ফাইলটি নিম্নরূপ লোড করুন (এটি অ্যান্ড্রয়েড ব্লকের আগে হতে হবে):

    গ্রোভি

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    

    কোটলিন

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    
  3. keystoreProperties অবজেক্টে সঞ্চিত স্বাক্ষর তথ্য ইনপুট করুন:

    গ্রোভি

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    

    কোটলিন

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    
  4. বিজ্ঞপ্তি বারে এখন সিঙ্ক এ ক্লিক করুন।

অ্যাপ সাইনিং সম্পর্কে আরও জানতে, আপনার অ্যাপ সাইন করুন পড়ুন।

অ্যাপ ডেভেলপমেন্ট সহজ করুন

নিম্নলিখিত টিপস আপনার অ্যান্ড্রয়েড অ্যাপ ডেভেলপ করা সহজ করতে সাহায্য করে৷

আপনার অ্যাপের কোডের সাথে কাস্টম ক্ষেত্র এবং সম্পদের মান শেয়ার করুন

বিল্ড টাইমে, Gradle BuildConfig ক্লাস তৈরি করে যাতে আপনার অ্যাপ কোড বর্তমান বিল্ড সম্পর্কে তথ্য পরিদর্শন করতে পারে। আপনি buildConfigField() পদ্ধতি ব্যবহার করে আপনার Gradle বিল্ড কনফিগারেশন ফাইল থেকে BuildConfig ক্লাসে কাস্টম ক্ষেত্র যোগ করতে পারেন এবং আপনার অ্যাপের রানটাইম কোডে সেই মানগুলি অ্যাক্সেস করতে পারেন। একইভাবে, আপনি resValue() এর সাথে অ্যাপ রিসোর্স মান যোগ করতে পারেন।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

আপনার অ্যাপ কোডে, আপনি নিম্নলিখিত বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন:

কোটলিন

...
Log.i(TAG, BuildConfig.BUILD_TIME)
Log.i(TAG, getString(R.string.build_time))

জাভা

...
Log.i(TAG, BuildConfig.BUILD_TIME);
Log.i(TAG, getString(R.string.build_time));

ম্যানিফেস্টের সাথে বৈশিষ্ট্য শেয়ার করুন

কিছু ক্ষেত্রে, আপনাকে আপনার ম্যানিফেস্ট এবং কোড উভয়েই একই সম্পত্তি ঘোষণা করতে হতে পারে (উদাহরণস্বরূপ, যখন FileProvider জন্য কর্তৃপক্ষ ঘোষণা করা হয়)। একটি পরিবর্তন প্রতিফলিত করতে একাধিক অবস্থানে একই সম্পত্তি আপডেট করার পরিবর্তে, আপনার মডিউলের build.gradle ফাইলে একটি একক সম্পত্তি সংজ্ঞায়িত করুন যাতে এটি ম্যানিফেস্ট এবং আপনার কোড উভয়ের জন্য উপলব্ধ থাকে, যেমনটি নিম্নলিখিত নমুনায় দেখানো হয়েছে। আরও জানতে, ম্যানিফেস্টে ইনজেক্ট বিল্ড ভেরিয়েবল পড়ুন।

গ্রোভি

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    def filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders =
      [filesAuthority: filesAuthorityValue]
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

কোটলিন

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    val filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders["filesAuthority"] = filesAuthorityValue
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

আপনার ম্যানিফেস্টে, নিম্নরূপ স্থানধারক অ্যাক্সেস করুন:

<manifest>
  ...
  <application>
    ...
    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true">
      ...
    </provider>
  </application>
</manifest>

আপনার অ্যাপের কোডে FILES_AUTHORITY ক্ষেত্র অ্যাক্সেস করা এইরকম কিছু দেখায়:

কোটলিন

...
val contentUri: Uri = FileProvider.getUriForFile(context, BuildConfig.FILES_AUTHORITY, myFile)

জাভা

...
Uri contentUri = FileProvider.getUriForFile(getContext(),
  BuildConfig.FILES_AUTHORITY,
  myFile);
,

Gradle এবং Gradle-এর জন্য Android প্লাগইন আপনার Android অ্যাপ বা লাইব্রেরি কম্পাইল, তৈরি এবং প্যাকেজ করার একটি নমনীয় উপায় প্রদান করে। এই পৃষ্ঠাটি আপনাকে প্রতিটি বিল্ড থেকে সর্বাধিক পেতে সাহায্য করার জন্য কিছু দরকারী টিপস এবং কনফিগারেশন সংগ্রহ করে৷ আপনি যদি আপনার বিল্ডগুলিকে দ্রুততর করার উপায়গুলি সম্পর্কে জানতে চান তবে আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনি যদি Gradle-এ নতুন হয়ে থাকেন, তাহলে আপনার বিল্ড কনফিগার করুন পড়ে বুনিয়াদি শিখুন। এই পৃষ্ঠায় ব্যবহৃত বৈশিষ্ট্যগুলি সম্পর্কে আরও জানতে আপনি Android প্লাগইনের DSL রেফারেন্স ডকুমেন্টেশনও পরিদর্শন করতে পারেন৷

প্রকল্প এবং উত্স পরিচালনা করুন

আপনার প্রকল্পের মডিউল এবং তাদের উত্সগুলি পরিচালনা করার জন্য এখানে কিছু কনফিগারেশন রয়েছে৷ প্রকল্প এবং মডিউল তৈরি এবং পরিচালনার বিষয়ে আরও জানতে, প্রকল্প ওভারভিউ পড়ুন।

ডিফল্ট সোর্স সেট কনফিগারেশন পরিবর্তন করুন

আপনি মডিউল-স্তরের build.gradle ফাইলে sourceSets ব্লক ব্যবহার করতে পারেন যেখানে Gradle একটি সোর্স সেটের প্রতিটি উপাদানের জন্য ফাইল সংগ্রহ করতে দেখায়।

গ্রোভি

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.srcDirs = ['other/res1', 'other/res2']

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    getByName("main") {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.setSrcDirs("other/java")

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.setSrcDirs("other/res1", "other/res2")

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile("other/AndroidManifest.xml")
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
    }
  }
}
...

লাইব্রেরি এবং নির্ভরতা পরিচালনা করুন

Gradle নির্ভরতাগুলি পরিচালনা করার জন্য একটি শক্তিশালী প্রক্রিয়া প্রদান করে, সেগুলি দূরবর্তী লাইব্রেরি বা স্থানীয় লাইব্রেরি মডিউল হোক না কেন।

নির্ভরতা কনফিগারেশনের সাথে নির্দিষ্ট বিল্ডগুলি লক্ষ্য করুন

আপনি যদি শুধুমাত্র একটি নির্দিষ্ট বিল্ড ভেরিয়েন্ট সোর্স সেট বা টেস্টিং সোর্স সেটের জন্য নির্ভরতা চান, তাহলে ডিপেন্ডেন্সি কনফিগারেশনের নামটি ক্যাপিটালাইজ করুন এবং বিল্ড ভ্যারিয়েন্ট বা টেস্টিং সোর্স সেটের নামের সাথে এটিকে প্রিফিক্স করুন।

গ্রোভি

android {...}

// Creates Gradle dependency configurations to use in the dependencies block.
configurations {
  // For variants that combine a product flavor and build type, you need to
  // intitialize a placeholder for its dependency configuration.
  freeDebugRuntimeOnly{}
  ...
}

dependencies {
    // Adds an implementation dependency only to the "free" product flavor.
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

কোটলিন

android {...}

dependencies {
    // Use ""() notation for custom flavors and build types
    // Adds an implementation dependency only to the "free" product flavor.
    "freeImplementation"("com.google.firebase:firebase-ads:21.5.1")
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    "freeDebugRuntimeOnly"(fileTree("dir" to "libs", "include" to "*.jar"))
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}

আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করুন

Gradle এবং Android প্লাগইন আপনাকে বিল্ড ভেরিয়েন্ট কনফিগার করে একটি একক মডিউল থেকে আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে দেয়।

ডায়নামিক সংস্করণ কোড কনফিগার করুন

ডিফল্টরূপে, যখন Gradle আপনার প্রকল্পের জন্য APK তৈরি করে, তখন প্রতিটি APK-এর একই সংস্করণের তথ্য থাকে, যেমনটি মডিউল-স্তরের build.gradle ফাইলে উল্লেখ করা হয়েছে। যেহেতু Google Play Store একই অ্যাপের জন্য একাধিক APK মঞ্জুরি দেয় না যার সকলের কাছে একই সংস্করণের তথ্য রয়েছে, তাই আপনি Play Store এ আপলোড করার আগে প্রতিটি APK এর নিজস্ব অনন্য সংস্করণকোড আছে তা নিশ্চিত করতে হবে।

আপনি কাস্টম বিল্ড লজিক দিয়ে এটি করতে পারেন যা বিল্ড টাইমে প্রতিটি APK কে একটি ভিন্ন সংস্করণ কোড বরাদ্দ করে। উদাহরণস্বরূপ, প্রতিটি ABI-এর জন্য পৃথক APK তৈরি করার সময়, স্বয়ংক্রিয় APK সংস্করণ দেখতে এরকম কিছু দেখায়:

গ্রোভি

android {
  ...
  defaultConfig {
    ...
    versionCode 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3]

// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['hdpi': 1, 'xhdpi': 2, 'xxhdpi': 3, 'xxxhdpi': 4]

import com.android.build.OutputFile

// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->

  // Assigns a different version code for each output APK
  // other than the universal APK.
  variant.outputs.each { output ->

    // Stores the value of ext.abiCodes that is associated with the ABI for this variant.
    def baseAbiVersionCode =
            // Determines the ABI for this variant and returns the mapped value.
            project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))

    // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
    // the following code does not override the version code for universal APKs.
    // However, because we want universal APKs to have the lowest version code,
    // this outcome is desirable.
    if (baseAbiVersionCode != null) {

      // Assigns the new version code to versionCodeOverride, which changes the version code
      // for only the output APK, not for the variant itself. Skipping this step simply
      // causes Gradle to use the value of variant.versionCode for the APK.
      output.versionCodeOverride =
              baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}

কোটলিন

android {
  ...
  defaultConfig {
    ...
    versionCode = 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
val abiCodes = mapOf("armeabi-v7a" to 1, "mips" to 2, "x86" to 3)

// For per-density APKs, create a similar map like this:
// val densityCodes = mapOf("hdpi" to 1, "xhdpi" to 2, "xxhdpi" to 3, "xxxhdpi" to 4)

import com.android.build.api.variant.FilterConfiguration.FilterType.*

// For each APK output variant, override versionCode with a combination of
// abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
androidComponents {
    onVariants { variant ->

        // Assigns a different version code for each output APK
        // other than the universal APK.
        variant.outputs.forEach { output ->
            val name = output.filters.find { it.filterType == ABI }?.identifier

            // Stores the value of abiCodes that is associated with the ABI for this variant.
            val baseAbiCode = abiCodes[name]
            // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
            // the following code does not override the version code for universal APKs.
            // However, because we want universal APKs to have the lowest version code,
            // this outcome is desirable.
            if (baseAbiCode != null) {
                // Assigns the new version code to output.versionCode, which changes the version code
                // for only the output APK, not for the variant itself.
                output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0))
            }
        }
    }
}

একাধিক পণ্যের স্বাদ একত্রিত করুন

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

নিম্নলিখিত কোড নমুনাটি "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদগুলিকে গোষ্ঠীভুক্ত করতে একটি "মোড" স্বাদের মাত্রা তৈরি করতে flavorDimensions বৈশিষ্ট্য ব্যবহার করে এবং API স্তরের উপর ভিত্তি করে পণ্যের স্বাদ কনফিগারেশনের গ্রুপ করার জন্য একটি "এপিআই" ফ্লেভারের মাত্রা ব্যবহার করে। Gradle তারপর "মোড" মাত্রা থেকে "api" মাত্রার সাথে পণ্যের স্বাদকে একত্রিত করে।

গ্রোভি

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion '24'
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion '23'
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion '21'
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdkVersion(24)
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode = 30000 + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdkVersion(23)
      versionCode = 20000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdkVersion(21)
      versionCode = 10000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

ফিল্টার বৈকল্পিক

আপনি মডিউলের build.gradle ফাইলে variantFilter ব্লক ব্যবহার করে বিল্ড ভেরিয়েন্টগুলি ফিল্টার করতে পারেন যা আপনি চান না। নিম্নলিখিত নমুনা কোডটি গ্র্যাডলকে বলে যে "মিনএপি21" এবং "ডেমো" পণ্যের স্বাদগুলিকে একত্রিত করে এমন কোনও রূপ তৈরি না করতে:

গ্রোভি

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enabled = false
        }
    }
}
...

আপনার অ্যাপ পরীক্ষা করুন

স্থানীয় এবং সমন্বিত ইউনিট পরীক্ষা চালানোর বিষয়ে আরও জানতে, আপনার অ্যাপ পরীক্ষা করুন পড়ুন।

লিন্ট বিকল্পগুলি কনফিগার করুন

আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে lintOptions ব্লক ব্যবহার করে নির্দিষ্ট লিন্ট বিকল্পগুলি কনফিগার করতে পারেন। আপনার অ্যান্ড্রয়েড প্রকল্পের জন্য লিন্ট ব্যবহার সম্পর্কে আরও জানতে, লিন্টের সাথে আপনার কোড উন্নত করুন পড়ুন।

গ্রোভি

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable 'TypographyFractions','TypographyQuotes'
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly 'NewApi', 'InlinedApi'
        // If set to true, turns off analysis progress reporting by lint.
        quiet true
        // if set to true (default), stops the build if errors are found.
        abortOnError false
        // if true, only report errors.
        ignoreWarnings true
    }
}
...

কোটলিন

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable("TypographyFractions")
        disable("TypographyQuotes")
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable("RtlHardcoded")
        enable("RtlCompat")
        enable("RtlEnabled")
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly("NewApi", "InlinedApi")
        // If set to true, turns off analysis progress reporting by lint.
        quiet = true
        // if set to true (default), stops the build if errors are found.
        abortOnError = false
        // if true, only report errors.
        ignoreWarnings = true
    }
}
...

ইন্সট্রুমেন্টেশন ম্যানিফেস্ট সেটিংস কনফিগার করুন

যখন Gradle আপনার পরীক্ষার APK তৈরি করে, তখন এটি স্বয়ংক্রিয়ভাবে AndroidManifest.xml ফাইল তৈরি করে এবং <instrumentation> নোডের সাথে কনফিগার করে। আপনি এই নোডের জন্য কিছু সেটিংস পরিবর্তন করতে পারেন পরীক্ষা উৎস সেটে অন্য একটি ম্যানিফেস্ট ফাইল তৈরি করে অথবা আপনার মডিউল-স্তরের build.gradle ফাইল কনফিগার করে, যেমনটি নিম্নলিখিত কোড নমুনায় দেখানো হয়েছে।

গ্রোভি

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest true
  }
}
...

কোটলিন

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId = "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner = "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling = true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest = true
  }
}
...

পরীক্ষার বিল্ড টাইপ পরিবর্তন করুন

ডিফল্টরূপে, সমস্ত পরীক্ষা ডিবাগ বিল্ড টাইপের বিরুদ্ধে চলে। আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে testBuildType বৈশিষ্ট্য ব্যবহার করে এটিকে অন্য বিল্ড টাইপে পরিবর্তন করতে পারেন। উদাহরণস্বরূপ, আপনি যদি আপনার "স্টেজিং" বিল্ড টাইপের বিপরীতে আপনার পরীক্ষা চালাতে চান তবে নিম্নলিখিত স্নিপেটে দেখানো ফাইলটি সম্পাদনা করুন।

গ্রোভি

android {
    ...
    testBuildType "staging"
}

কোটলিন

android {
    ...
    testBuildType "staging"
}

Gradle পরীক্ষার বিকল্পগুলি কনফিগার করুন

Gradle কিভাবে আপনার সমস্ত পরীক্ষা চালায় তা পরিবর্তন করে এমন বিকল্পগুলি নির্দিষ্ট করতে, মডিউল-স্তরের build.gradletestOptions ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

কোটলিন

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

শুধুমাত্র স্থানীয় ইউনিট পরীক্ষার জন্য বিকল্পগুলি নির্দিষ্ট করতে, testOptions.unitTests ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

কোটলিন

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

আপনার বিল্ড অপ্টিমাইজ করুন

এই বিভাগটি আপনার সম্পূর্ণ এবং ক্রমবর্ধমান বিল্ডগুলির গতি বাড়ানোর জন্য কিছু কনফিগারেশন সরবরাহ করে। আরও জানতে, আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনার কোড সঙ্কুচিত করুন

অ্যান্ড্রয়েড স্টুডিও R8 ব্যবহার করে, যা আপনার কোড সঙ্কুচিত করতে ProGuard নিয়মের ফাইলগুলি ব্যবহার করে। নতুন প্রকল্পগুলির জন্য, Android স্টুডিও অ্যান্ড্রয়েড SDK-এর tools/proguard/folder থেকে একটি ডিফল্ট সেটিংস ফাইল ( proguard-android.txt ) ব্যবহার করে। আরও বেশি কোড সঙ্কুচিত করার জন্য, একই অবস্থানে থাকা proguard-android-optimize.txt ফাইলটি ব্যবহার করে দেখুন৷

গ্রোভি

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

কোটলিন

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

প্রতিটি বিল্ড ভেরিয়েন্টের জন্য নির্দিষ্ট নিয়ম যোগ করতে, প্রতিটি স্বাদের জন্য অতিরিক্ত proguardFiles বৈশিষ্ট্য কনফিগার করুন। উদাহরণস্বরূপ, নিম্নলিখিত নমুনা "flavor2" তে flavor2-rules.pro যোগ করে। এখন "flavor2" এর রিলিজ সংস্করণটি তিনটি নিয়ম ফাইল ব্যবহার করে কারণ রিলিজ ব্লক থেকেও প্রয়োগ করা হয়।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

আপনার অ্যাপ্লিকেশন প্রকাশ করুন

Google Play-তে আপনার অ্যাপ প্রকাশ করার বিষয়ে আরও জানতে, আপনার অ্যাপ প্রকাশ করুন পড়ুন।

আপনার অ্যাপে সাইন ইন করুন

যদিও অ্যান্ড্রয়েড স্টুডিও UI থেকে রিলিজ বিল্ডের জন্য সাইনিং কনফিগার করার একটি সহজ উপায় প্রদান করে, আপনি আপনার মডিউলের build.gradle ফাইলে signingConfigs ব্লক ম্যানুয়ালি কনফিগার করতে পারেন:

গ্রোভি

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

আপনার প্রকল্প থেকে ব্যক্তিগত স্বাক্ষর তথ্য সরান

ডিফল্টরূপে, সাইনিং কনফিগারেশনগুলি মডিউলের build.gradle ফাইলে প্লেইন টেক্সটে রেকর্ড করা হয়। আপনি যদি একটি দল বা একটি ওপেন-সোর্স প্রকল্পের সাথে কাজ করেন, তাহলে আপনি এই সংবেদনশীল তথ্যটিকে বিল্ড ফাইলের বাইরে নিয়ে যেতে পারেন।

  1. আপনার প্রকল্পের রুট ডিরেক্টরিতে keystore.properties নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত তথ্য অন্তর্ভুক্ত করুন:
    storePassword=myStorePassword
    keyPassword=myKeyPassword
    keyAlias=myKeyAlias
    storeFile=myStoreFileLocation
    
  2. আপনার build.gradle ফাইলে, keystore.properties ফাইলটি নিম্নরূপ লোড করুন (এটি অ্যান্ড্রয়েড ব্লকের আগে হতে হবে):

    গ্রোভি

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    

    কোটলিন

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    
  3. keystoreProperties অবজেক্টে সঞ্চিত স্বাক্ষর তথ্য ইনপুট করুন:

    গ্রোভি

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    

    কোটলিন

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    
  4. বিজ্ঞপ্তি বারে এখন সিঙ্ক এ ক্লিক করুন।

অ্যাপ সাইনিং সম্পর্কে আরও জানতে, আপনার অ্যাপ সাইন করুন পড়ুন।

অ্যাপ ডেভেলপমেন্ট সহজ করুন

নিম্নলিখিত টিপস আপনার অ্যান্ড্রয়েড অ্যাপ ডেভেলপ করা সহজ করতে সাহায্য করে৷

আপনার অ্যাপের কোডের সাথে কাস্টম ক্ষেত্র এবং সম্পদের মান শেয়ার করুন

বিল্ড টাইমে, Gradle BuildConfig ক্লাস তৈরি করে যাতে আপনার অ্যাপ কোড বর্তমান বিল্ড সম্পর্কে তথ্য পরিদর্শন করতে পারে। আপনি buildConfigField() পদ্ধতি ব্যবহার করে আপনার Gradle বিল্ড কনফিগারেশন ফাইল থেকে BuildConfig ক্লাসে কাস্টম ক্ষেত্র যোগ করতে পারেন এবং আপনার অ্যাপের রানটাইম কোডে সেই মানগুলি অ্যাক্সেস করতে পারেন। একইভাবে, আপনি resValue() এর সাথে অ্যাপ রিসোর্স মান যোগ করতে পারেন।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

আপনার অ্যাপ কোডে, আপনি নিম্নলিখিত বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন:

কোটলিন

...
Log.i(TAG, BuildConfig.BUILD_TIME)
Log.i(TAG, getString(R.string.build_time))

জাভা

...
Log.i(TAG, BuildConfig.BUILD_TIME);
Log.i(TAG, getString(R.string.build_time));

ম্যানিফেস্টের সাথে বৈশিষ্ট্য শেয়ার করুন

কিছু ক্ষেত্রে, আপনাকে আপনার ম্যানিফেস্ট এবং কোড উভয়েই একই সম্পত্তি ঘোষণা করতে হতে পারে (উদাহরণস্বরূপ, যখন FileProvider জন্য কর্তৃপক্ষ ঘোষণা করা হয়)। একটি পরিবর্তন প্রতিফলিত করতে একাধিক অবস্থানে একই সম্পত্তি আপডেট করার পরিবর্তে, আপনার মডিউলের build.gradle ফাইলে একটি একক সম্পত্তি সংজ্ঞায়িত করুন যাতে এটি ম্যানিফেস্ট এবং আপনার কোড উভয়ের জন্য উপলব্ধ থাকে, যেমনটি নিম্নলিখিত নমুনায় দেখানো হয়েছে। আরও জানতে, ম্যানিফেস্টে ইনজেক্ট বিল্ড ভেরিয়েবল পড়ুন।

গ্রোভি

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    def filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders =
      [filesAuthority: filesAuthorityValue]
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

কোটলিন

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    val filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders["filesAuthority"] = filesAuthorityValue
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

আপনার ম্যানিফেস্টে, নিম্নরূপ স্থানধারক অ্যাক্সেস করুন:

<manifest>
  ...
  <application>
    ...
    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true">
      ...
    </provider>
  </application>
</manifest>

আপনার অ্যাপের কোডে FILES_AUTHORITY ক্ষেত্র অ্যাক্সেস করা এইরকম কিছু দেখায়:

কোটলিন

...
val contentUri: Uri = FileProvider.getUriForFile(context, BuildConfig.FILES_AUTHORITY, myFile)

জাভা

...
Uri contentUri = FileProvider.getUriForFile(getContext(),
  BuildConfig.FILES_AUTHORITY,
  myFile);
,

Gradle এবং Gradle-এর জন্য Android প্লাগইন আপনার Android অ্যাপ বা লাইব্রেরি কম্পাইল, তৈরি এবং প্যাকেজ করার একটি নমনীয় উপায় প্রদান করে। এই পৃষ্ঠাটি আপনাকে প্রতিটি বিল্ড থেকে সর্বাধিক পেতে সাহায্য করার জন্য কিছু দরকারী টিপস এবং কনফিগারেশন সংগ্রহ করে৷ আপনি যদি আপনার বিল্ডগুলিকে দ্রুততর করার উপায়গুলি সম্পর্কে জানতে চান তবে আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনি যদি Gradle-এ নতুন হয়ে থাকেন, তাহলে আপনার বিল্ড কনফিগার করুন পড়ে বুনিয়াদি শিখুন। এই পৃষ্ঠায় ব্যবহৃত বৈশিষ্ট্যগুলি সম্পর্কে আরও জানতে আপনি Android প্লাগইনের DSL রেফারেন্স ডকুমেন্টেশনও পরিদর্শন করতে পারেন৷

প্রকল্প এবং উত্স পরিচালনা করুন

আপনার প্রকল্পের মডিউল এবং তাদের উত্সগুলি পরিচালনা করার জন্য এখানে কিছু কনফিগারেশন রয়েছে৷ প্রকল্প এবং মডিউল তৈরি এবং পরিচালনার বিষয়ে আরও জানতে, প্রকল্প ওভারভিউ পড়ুন।

ডিফল্ট সোর্স সেট কনফিগারেশন পরিবর্তন করুন

আপনি মডিউল-স্তরের build.gradle ফাইলে sourceSets ব্লক ব্যবহার করতে পারেন যেখানে Gradle একটি সোর্স সেটের প্রতিটি উপাদানের জন্য ফাইল সংগ্রহ করতে দেখায়।

গ্রোভি

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.srcDirs = ['other/res1', 'other/res2']

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    getByName("main") {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.setSrcDirs("other/java")

      // When you list multiple directories, Gradle uses all of them to collect
      // sources. You should avoid specifying a directory which is a parent to one
      // or more other directories you specify.
      res.setSrcDirs("other/res1", "other/res2")

      // For each source set, you can specify only one Android manifest.
      // The following points Gradle to a different manifest for this source set.
      manifest.srcFile("other/AndroidManifest.xml")
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying
      // the configuration below for the androidTest source set, Gradle looks for
      // Java sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
    }
  }
}
...

লাইব্রেরি এবং নির্ভরতা পরিচালনা করুন

Gradle নির্ভরতাগুলি পরিচালনা করার জন্য একটি শক্তিশালী প্রক্রিয়া প্রদান করে, সেগুলি দূরবর্তী লাইব্রেরি বা স্থানীয় লাইব্রেরি মডিউল হোক না কেন।

নির্ভরতা কনফিগারেশনের সাথে নির্দিষ্ট বিল্ডগুলি লক্ষ্য করুন

আপনি যদি শুধুমাত্র একটি নির্দিষ্ট বিল্ড ভেরিয়েন্ট সোর্স সেট বা টেস্টিং সোর্স সেটের জন্য নির্ভরতা চান, তাহলে ডিপেন্ডেন্সি কনফিগারেশনের নামটি ক্যাপিটালাইজ করুন এবং বিল্ড ভ্যারিয়েন্ট বা টেস্টিং সোর্স সেটের নামের সাথে এটিকে প্রিফিক্স করুন।

গ্রোভি

android {...}

// Creates Gradle dependency configurations to use in the dependencies block.
configurations {
  // For variants that combine a product flavor and build type, you need to
  // intitialize a placeholder for its dependency configuration.
  freeDebugRuntimeOnly{}
  ...
}

dependencies {
    // Adds an implementation dependency only to the "free" product flavor.
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

কোটলিন

android {...}

dependencies {
    // Use ""() notation for custom flavors and build types
    // Adds an implementation dependency only to the "free" product flavor.
    "freeImplementation"("com.google.firebase:firebase-ads:21.5.1")
    // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    "freeDebugRuntimeOnly"(fileTree("dir" to "libs", "include" to "*.jar"))
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")
    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}

আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করুন

Gradle এবং Android প্লাগইন আপনাকে বিল্ড ভেরিয়েন্ট কনফিগার করে একটি একক মডিউল থেকে আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে দেয়।

ডায়নামিক সংস্করণ কোড কনফিগার করুন

ডিফল্টরূপে, যখন Gradle আপনার প্রকল্পের জন্য APK তৈরি করে, তখন প্রতিটি APK-এর একই সংস্করণের তথ্য থাকে, যেমনটি মডিউল-স্তরের build.gradle ফাইলে উল্লেখ করা হয়েছে। যেহেতু Google Play Store একই অ্যাপের জন্য একাধিক APK মঞ্জুরি দেয় না যার সকলের কাছে একই সংস্করণের তথ্য রয়েছে, তাই আপনি Play Store এ আপলোড করার আগে প্রতিটি APK এর নিজস্ব অনন্য সংস্করণকোড আছে তা নিশ্চিত করতে হবে।

আপনি কাস্টম বিল্ড লজিক দিয়ে এটি করতে পারেন যা বিল্ড টাইমে প্রতিটি APK কে একটি ভিন্ন সংস্করণ কোড বরাদ্দ করে। উদাহরণস্বরূপ, প্রতিটি ABI-এর জন্য পৃথক APK তৈরি করার সময়, স্বয়ংক্রিয় APK সংস্করণ দেখতে এরকম কিছু দেখায়:

গ্রোভি

android {
  ...
  defaultConfig {
    ...
    versionCode 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3]

// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['hdpi': 1, 'xhdpi': 2, 'xxhdpi': 3, 'xxxhdpi': 4]

import com.android.build.OutputFile

// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->

  // Assigns a different version code for each output APK
  // other than the universal APK.
  variant.outputs.each { output ->

    // Stores the value of ext.abiCodes that is associated with the ABI for this variant.
    def baseAbiVersionCode =
            // Determines the ABI for this variant and returns the mapped value.
            project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))

    // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
    // the following code does not override the version code for universal APKs.
    // However, because we want universal APKs to have the lowest version code,
    // this outcome is desirable.
    if (baseAbiVersionCode != null) {

      // Assigns the new version code to versionCodeOverride, which changes the version code
      // for only the output APK, not for the variant itself. Skipping this step simply
      // causes Gradle to use the value of variant.versionCode for the APK.
      output.versionCodeOverride =
              baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}

কোটলিন

android {
  ...
  defaultConfig {
    ...
    versionCode = 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
val abiCodes = mapOf("armeabi-v7a" to 1, "mips" to 2, "x86" to 3)

// For per-density APKs, create a similar map like this:
// val densityCodes = mapOf("hdpi" to 1, "xhdpi" to 2, "xxhdpi" to 3, "xxxhdpi" to 4)

import com.android.build.api.variant.FilterConfiguration.FilterType.*

// For each APK output variant, override versionCode with a combination of
// abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
androidComponents {
    onVariants { variant ->

        // Assigns a different version code for each output APK
        // other than the universal APK.
        variant.outputs.forEach { output ->
            val name = output.filters.find { it.filterType == ABI }?.identifier

            // Stores the value of abiCodes that is associated with the ABI for this variant.
            val baseAbiCode = abiCodes[name]
            // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
            // the following code does not override the version code for universal APKs.
            // However, because we want universal APKs to have the lowest version code,
            // this outcome is desirable.
            if (baseAbiCode != null) {
                // Assigns the new version code to output.versionCode, which changes the version code
                // for only the output APK, not for the variant itself.
                output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0))
            }
        }
    }
}

একাধিক পণ্যের স্বাদ একত্রিত করুন

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

নিম্নলিখিত কোড নমুনাটি "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদগুলিকে গোষ্ঠীভুক্ত করতে একটি "মোড" স্বাদের মাত্রা তৈরি করতে flavorDimensions বৈশিষ্ট্য ব্যবহার করে এবং API স্তরের উপর ভিত্তি করে পণ্যের স্বাদ কনফিগারেশনের গ্রুপ করার জন্য একটি "এপিআই" ফ্লেভারের মাত্রা ব্যবহার করে। Gradle তারপর "মোড" মাত্রা থেকে "api" মাত্রার সাথে পণ্যের স্বাদকে একত্রিত করে।

গ্রোভি

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion '24'
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion '23'
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion '21'
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdkVersion(24)
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
      versionCode = 30000 + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdkVersion(23)
      versionCode = 20000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdkVersion(21)
      versionCode = 10000  + android.defaultConfig.versionCode
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

ফিল্টার বৈকল্পিক

আপনি মডিউলের build.gradle ফাইলে variantFilter ব্লক ব্যবহার করে বিল্ড ভেরিয়েন্টগুলি ফিল্টার করতে পারেন যা আপনি চান না। নিম্নলিখিত নমুনা কোডটি গ্র্যাডলকে বলে যে "মিনএপি21" এবং "ডেমো" পণ্যের স্বাদগুলিকে একত্রিত করে এমন কোনও রূপ তৈরি না করতে:

গ্রোভি

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enabled = false
        }
    }
}
...

আপনার অ্যাপ পরীক্ষা করুন

স্থানীয় এবং সমন্বিত ইউনিট পরীক্ষা চালানোর বিষয়ে আরও জানতে, আপনার অ্যাপ পরীক্ষা করুন পড়ুন।

লিন্ট বিকল্পগুলি কনফিগার করুন

আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে lintOptions ব্লক ব্যবহার করে নির্দিষ্ট লিন্ট বিকল্পগুলি কনফিগার করতে পারেন। আপনার অ্যান্ড্রয়েড প্রকল্পের জন্য লিন্ট ব্যবহার সম্পর্কে আরও জানতে, লিন্টের সাথে আপনার কোড উন্নত করুন পড়ুন।

গ্রোভি

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable 'TypographyFractions','TypographyQuotes'
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly 'NewApi', 'InlinedApi'
        // If set to true, turns off analysis progress reporting by lint.
        quiet true
        // if set to true (default), stops the build if errors are found.
        abortOnError false
        // if true, only report errors.
        ignoreWarnings true
    }
}
...

কোটলিন

android {
    ...
    lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable("TypographyFractions")
        disable("TypographyQuotes")
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable("RtlHardcoded")
        enable("RtlCompat")
        enable("RtlEnabled")
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        checkOnly("NewApi", "InlinedApi")
        // If set to true, turns off analysis progress reporting by lint.
        quiet = true
        // if set to true (default), stops the build if errors are found.
        abortOnError = false
        // if true, only report errors.
        ignoreWarnings = true
    }
}
...

ইন্সট্রুমেন্টেশন ম্যানিফেস্ট সেটিংস কনফিগার করুন

যখন Gradle আপনার পরীক্ষার APK তৈরি করে, তখন এটি স্বয়ংক্রিয়ভাবে AndroidManifest.xml ফাইল তৈরি করে এবং <instrumentation> নোডের সাথে কনফিগার করে। আপনি এই নোডের জন্য কিছু সেটিংস পরিবর্তন করতে পারেন পরীক্ষা উৎস সেটে অন্য একটি ম্যানিফেস্ট ফাইল তৈরি করে অথবা আপনার মডিউল-স্তরের build.gradle ফাইল কনফিগার করে, যেমনটি নিম্নলিখিত কোড নমুনায় দেখানো হয়েছে।

গ্রোভি

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest true
  }
}
...

কোটলিন

android {
  ...
  // Each product flavor you configure can override properties in the
  // defaultConfig block. To learn more, go to Configure Product Flavors.
  defaultConfig {
    ...
    // Specifies the application ID for the test APK.
    testApplicationId = "com.test.foo"
    // Specifies the fully-qualified class name of the test instrumentation runner.
    testInstrumentationRunner = "android.test.InstrumentationTestRunner"
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation
    // class is running.
    testHandleProfiling = true
    // If set to 'true', indicates that the Android system should run the instrumentation
    // class as a functional test. The default value is 'false'
    testFunctionalTest = true
  }
}
...

পরীক্ষার বিল্ড টাইপ পরিবর্তন করুন

ডিফল্টরূপে, সমস্ত পরীক্ষা ডিবাগ বিল্ড টাইপের বিরুদ্ধে চলে। আপনি আপনার মডিউল-স্তরের build.gradle ফাইলে testBuildType বৈশিষ্ট্য ব্যবহার করে এটিকে অন্য বিল্ড টাইপে পরিবর্তন করতে পারেন। উদাহরণস্বরূপ, আপনি যদি আপনার "স্টেজিং" বিল্ড টাইপের বিপরীতে আপনার পরীক্ষা চালাতে চান তবে নিম্নলিখিত স্নিপেটে দেখানো ফাইলটি সম্পাদনা করুন।

গ্রোভি

android {
    ...
    testBuildType "staging"
}

কোটলিন

android {
    ...
    testBuildType "staging"
}

Gradle পরীক্ষার বিকল্পগুলি কনফিগার করুন

Gradle কিভাবে আপনার সমস্ত পরীক্ষা চালায় তা পরিবর্তন করে এমন বিকল্পগুলি নির্দিষ্ট করতে, মডিউল-স্তরের build.gradletestOptions ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

কোটলিন

android {
  ...
  // Encapsulates options for running tests.
  testOptions {
    // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
    // in the path_to_your_project/module_name/build/outputs/reports/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports"
    // Changes the directory where Gradle saves test results. By default, Gradle saves test results
    // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
    // '$rootDir' sets the path relative to the root directory of the current project.
    resultsDir "$rootDir/test-results"
  }
}

শুধুমাত্র স্থানীয় ইউনিট পরীক্ষার জন্য বিকল্পগুলি নির্দিষ্ট করতে, testOptions.unitTests ব্লক কনফিগার করুন।

গ্রোভি

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

কোটলিন

android {
  ...
  testOptions {
    ...
    // Encapsulates options for local unit tests.
    unitTests {
      // By default, local unit tests throw an exception any time the code you are testing tries to access
      // Android platform APIs (unless you mock Android dependencies yourself or with a testing
      // framework like Mockito). However, you can enable the following property so that the test
      // returns either null or zero when accessing platform APIs, rather than throwing an exception.
      returnDefaultValues true

      // Encapsulates options for controlling how Gradle executes local unit tests. For a list
      // of all the options you can specify, read Gradle's reference documentation.
      all {
        // Sets JVM argument(s) for the test JVM(s).
        jvmArgs '-XX:MaxPermSize=256m'

        // You can also check the task name to apply options to only the tests you specify.
        if (it.name == 'testDebugUnitTest') {
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}

আপনার বিল্ড অপ্টিমাইজ করুন

এই বিভাগটি আপনার সম্পূর্ণ এবং ক্রমবর্ধমান বিল্ডগুলির গতি বাড়ানোর জন্য কিছু কনফিগারেশন সরবরাহ করে। আরও জানতে, আপনার বিল্ড স্পিড অপ্টিমাইজ করুন পড়ুন।

আপনার কোড সঙ্কুচিত করুন

অ্যান্ড্রয়েড স্টুডিও R8 ব্যবহার করে, যা আপনার কোড সঙ্কুচিত করতে ProGuard নিয়মের ফাইলগুলি ব্যবহার করে। নতুন প্রকল্পগুলির জন্য, Android স্টুডিও অ্যান্ড্রয়েড SDK-এর tools/proguard/folder থেকে একটি ডিফল্ট সেটিংস ফাইল ( proguard-android.txt ) ব্যবহার করে। আরও বেশি কোড সঙ্কুচিত করার জন্য, একই অবস্থানে থাকা proguard-android-optimize.txt ফাইলটি ব্যবহার করে দেখুন৷

গ্রোভি

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

কোটলিন

android {
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                                           'proguard-rules.pro'
    }
  }
  ...
}
...

প্রতিটি বিল্ড ভেরিয়েন্টের জন্য নির্দিষ্ট নিয়ম যোগ করতে, প্রতিটি স্বাদের জন্য অতিরিক্ত proguardFiles বৈশিষ্ট্য কনফিগার করুন। উদাহরণস্বরূপ, নিম্নলিখিত নমুনা "flavor2" তে flavor2-rules.pro যোগ করে। এখন "flavor2" এর রিলিজ সংস্করণটি তিনটি নিয়ম ফাইল ব্যবহার করে কারণ রিলিজ ব্লক থেকেও প্রয়োগ করা হয়।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'),
             'proguard-rules.pro'
    }
  }
  productFlavors {
    flavor1 {
      ...
    }
    flavor2 {
      proguardFile 'flavor2-rules.pro'
    }
  }
}
...

আপনার অ্যাপ্লিকেশন প্রকাশ করুন

Google Play-তে আপনার অ্যাপ প্রকাশ করার বিষয়ে আরও জানতে, আপনার অ্যাপ প্রকাশ করুন পড়ুন।

আপনার অ্যাপে সাইন ইন করুন

যদিও অ্যান্ড্রয়েড স্টুডিও UI থেকে রিলিজ বিল্ডের জন্য সাইনিং কনফিগার করার একটি সহজ উপায় প্রদান করে, আপনি আপনার মডিউলের build.gradle ফাইলে signingConfigs ব্লক ম্যানুয়ালি কনফিগার করতে পারেন:

গ্রোভি

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

কোটলিন

android {
  ...
  defaultConfig { ... }

  // Encapsulates signing configurations.
  signingConfigs {
    // Creates a signing configuration called "release".
    release {
      // Specifies the path to your keystore file.
      storeFile file("my-release-key.jks")
      // Specifies the password for your keystore.
      storePassword "password"
      // Specifies the identifying name for your key.
      keyAlias "my-alias"
      // Specifies the password for your key.
      keyPassword "password"
    }
  }
  buildTypes {
    release {
      // Adds the "release" signing configuration to the release build type.
      signingConfig signingConfigs.release
      ...
    }
  }
}
...

আপনার প্রকল্প থেকে ব্যক্তিগত স্বাক্ষর তথ্য সরান

ডিফল্টরূপে, সাইনিং কনফিগারেশনগুলি মডিউলের build.gradle ফাইলে প্লেইন টেক্সটে রেকর্ড করা হয়। আপনি যদি একটি দল বা একটি ওপেন-সোর্স প্রকল্পের সাথে কাজ করেন, তাহলে আপনি এই সংবেদনশীল তথ্যটিকে বিল্ড ফাইলের বাইরে নিয়ে যেতে পারেন।

  1. আপনার প্রকল্পের রুট ডিরেক্টরিতে keystore.properties নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত তথ্য অন্তর্ভুক্ত করুন:
    storePassword=myStorePassword
    keyPassword=myKeyPassword
    keyAlias=myKeyAlias
    storeFile=myStoreFileLocation
    
  2. আপনার build.gradle ফাইলে, keystore.properties ফাইলটি নিম্নরূপ লোড করুন (এটি অ্যান্ড্রয়েড ব্লকের আগে হতে হবে):

    গ্রোভি

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    

    কোটলিন

    // Creates a variable called keystorePropertiesFile, and initializes it to the
    // keystore.properties file.
    def keystorePropertiesFile = rootProject.file("keystore.properties")
    
    // Initializes a new Properties() object called keystoreProperties.
    def keystoreProperties = new Properties()
    
    // Loads the keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
    android {
      ...
    }
    ...
    
  3. keystoreProperties অবজেক্টে সঞ্চিত স্বাক্ষর তথ্য ইনপুট করুন:

    গ্রোভি

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    

    কোটলিন

    android {
      signingConfigs {
        config {
          keyAlias keystoreProperties['keyAlias']
          keyPassword keystoreProperties['keyPassword']
          storeFile file(keystoreProperties['storeFile'])
          storePassword keystoreProperties['storePassword']
        }
      }
      ...
    }
    ...
    
  4. বিজ্ঞপ্তি বারে এখন সিঙ্ক এ ক্লিক করুন।

অ্যাপ সাইনিং সম্পর্কে আরও জানতে, আপনার অ্যাপ সাইন করুন পড়ুন।

অ্যাপ ডেভেলপমেন্ট সহজ করুন

নিম্নলিখিত টিপস আপনার অ্যান্ড্রয়েড অ্যাপ ডেভেলপ করা সহজ করতে সাহায্য করে৷

আপনার অ্যাপের কোডের সাথে কাস্টম ক্ষেত্র এবং সম্পদের মান শেয়ার করুন

বিল্ড টাইমে, Gradle BuildConfig ক্লাস তৈরি করে যাতে আপনার অ্যাপ কোড বর্তমান বিল্ড সম্পর্কে তথ্য পরিদর্শন করতে পারে। আপনি buildConfigField() পদ্ধতি ব্যবহার করে আপনার Gradle বিল্ড কনফিগারেশন ফাইল থেকে BuildConfig ক্লাসে কাস্টম ক্ষেত্র যোগ করতে পারেন এবং আপনার অ্যাপের রানটাইম কোডে সেই মানগুলি অ্যাক্সেস করতে পারেন। একইভাবে, আপনি resValue() এর সাথে অ্যাপ রিসোর্স মান যোগ করতে পারেন।

গ্রোভি

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

কোটলিন

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If these rebuild dynamically, they can interfere with
      // Apply Changes as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
...

আপনার অ্যাপ কোডে, আপনি নিম্নলিখিত বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন:

কোটলিন

...
Log.i(TAG, BuildConfig.BUILD_TIME)
Log.i(TAG, getString(R.string.build_time))

জাভা

...
Log.i(TAG, BuildConfig.BUILD_TIME);
Log.i(TAG, getString(R.string.build_time));

ম্যানিফেস্টের সাথে বৈশিষ্ট্য শেয়ার করুন

কিছু ক্ষেত্রে, আপনাকে আপনার ম্যানিফেস্ট এবং কোড উভয়েই একই সম্পত্তি ঘোষণা করতে হতে পারে (উদাহরণস্বরূপ, যখন FileProvider জন্য কর্তৃপক্ষ ঘোষণা করা হয়)। একটি পরিবর্তন প্রতিফলিত করতে একাধিক অবস্থানে একই সম্পত্তি আপডেট করার পরিবর্তে, আপনার মডিউলের build.gradle ফাইলে একটি একক সম্পত্তি সংজ্ঞায়িত করুন যাতে এটি ম্যানিফেস্ট এবং আপনার কোড উভয়ের জন্য উপলব্ধ থাকে, যেমনটি নিম্নলিখিত নমুনায় দেখানো হয়েছে। আরও জানতে, ম্যানিফেস্টে ইনজেক্ট বিল্ড ভেরিয়েবল পড়ুন।

গ্রোভি

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    def filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders =
      [filesAuthority: filesAuthorityValue]
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

কোটলিন

android {
  // For settings specific to a product flavor, configure these properties
  // for each flavor in the productFlavors block.
  defaultConfig {
    // Creates a property for the FileProvider authority.
    val filesAuthorityValue = applicationId + ".files"
    // Creates a placeholder property to use in the manifest.
    manifestPlaceholders["filesAuthority"] = filesAuthorityValue
      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

আপনার ম্যানিফেস্টে, নিম্নরূপ স্থানধারক অ্যাক্সেস করুন:

<manifest>
  ...
  <application>
    ...
    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true">
      ...
    </provider>
  </application>
</manifest>

আপনার অ্যাপের কোডে FILES_AUTHORITY ক্ষেত্র অ্যাক্সেস করা এইরকম কিছু দেখায়:

কোটলিন

...
val contentUri: Uri = FileProvider.getUriForFile(context, BuildConfig.FILES_AUTHORITY, myFile)

জাভা

...
Uri contentUri = FileProvider.getUriForFile(getContext(),
  BuildConfig.FILES_AUTHORITY,
  myFile);