android - ग्रैडल में कार्यान्वयन और संकलन के बीच क्या अंतर है?




gradle android-studio (4)

Android Studio 3.0 में अद्यतन करने और एक नई परियोजना बनाने के बाद, मैंने देखा कि build.gradle में compile बजाय नई निर्भरता जोड़ने का एक नया तरीका है, implementation और testCompile बजाय testCompile implementation है।

उदाहरण:

 implementation 'com.android.support:appcompat-v7:25.0.0'
 testImplementation 'junit:junit:4.12'

के बजाय

 compile 'com.android.support:appcompat-v7:25.0.0'
 testCompile 'junit:junit:4.12'

उनके बीच क्या अंतर है और मुझे क्या उपयोग करना चाहिए?


यह उत्तर किसी परियोजना पर implementation , api और compile बीच अंतर को प्रदर्शित करेगा।

मान लीजिए कि मेरे पास तीन ग्रेड मॉड्यूल के साथ एक परियोजना है:

  • एप्लिकेशन (एक Android आवेदन)
  • myandroidlibrary (एक Android लाइब्रेरी)
  • myjavalibrary (एक जावा पुस्तकालय)

app पर निर्भरता के रूप में myandroidlibrary है। myandroidlibrary निर्भरता के रूप में myjavalibrary है।

myjavalibrary में MySecret क्लास है

public class MySecret {

    public static String getSecret() {
        return "Money";
    }
}

myandroidlibrary में MyAndroidComponent class है जो MySecret वर्ग से मान में हेरफेर करता है।

public class MyAndroidComponent {

    private static String component = MySecret.getSecret();

    public static String getComponent() {
        return "My component: " + component;
    }    
}

अंत में, app केवल myandroidlibrary से मूल्य में रुचि myandroidlibrary

TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());

अब, चलो निर्भरता के बारे में बात करते हैं ...

app को उपभोग करने की आवश्यकता है :myandroidlibrary , ताकि app बिल्ड में हो। implementation उपयोग करें।

( नोट : आप एपीआई / संकलन का भी उपयोग कर सकते हैं। लेकिन एक क्षण के लिए उस विचार को पकड़ें।)

dependencies {
    implementation project(':myandroidlibrary')      
}

आपको क्या लगता है myandroidlibrary build.gradle को myandroidlibrary दिखना चाहिए? हमें किस स्कोप का उपयोग करना चाहिए?

हमारे पास तीन विकल्प हैं:

dependencies {
    // Option #1
    implementation project(':myjavalibrary') 
    // Option #2
    compile project(':myjavalibrary')      
    // Option #3
    api project(':myjavalibrary')           
}

उनके बीच क्या अंतर है और मुझे क्या उपयोग करना चाहिए?

संकलन या आपी (विकल्प # 2 या # 3)

यदि आप compile या api का उपयोग कर रहे हैं। हमारा Android एप्लिकेशन अब myandroidcomponent निर्भरता का उपयोग करने में सक्षम है, जो एक MySecret वर्ग है।

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());

कार्यान्वयन (विकल्प # 1)

यदि आप implementation कॉन्फ़िगरेशन का उपयोग कर रहे हैं, तो MySecret उजागर नहीं है।

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can NOT access MySecret
textView.setText(MySecret.getSecret()); // Won't even compile

तो, आपको कौन सा कॉन्फ़िगरेशन चुनना चाहिए? यह वास्तव में आपकी आवश्यकता पर निर्भर करता है।

यदि आप निर्भरता को उजागर करना चाहते हैं तो api या compile उपयोग करें।

यदि आप निर्भरता (अपने आंतरिक मॉड्यूल को छिपाना) को उजागर नहीं करना चाहते हैं तो implementation उपयोग करें।

ध्यान दें:

यह ग्रैडल कॉन्फ़िगरेशन का सिर्फ एक सार है, तालिका 49.1 का संदर्भ लें जावा लाइब्रेरी प्लगइन - अधिक विस्तृत विवरण के लिए निर्भरता घोषित करने के लिए उपयोग किए जाने वाले कॉन्फ़िगरेशन

इस उत्तर के लिए नमूना परियोजना https://github.com/aldoKelvianto/ImplementationVsCompile पर उपलब्ध है


Compile विन्यास को हटा दिया गया था और इसे implementation या api द्वारा प्रतिस्थापित किया जाना चाहिए।

आप डॉक्स को https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation पर पढ़ सकते हैं।

संक्षिप्त भाग -

मानक जावा प्लगइन और जावा लाइब्रेरी प्लगइन के बीच महत्वपूर्ण अंतर यह है कि बाद वाला उपभोक्ताओं के लिए एक एपीआई की अवधारणा का परिचय देता है। एक पुस्तकालय एक जावा घटक है जिसका उपयोग अन्य घटकों द्वारा किया जाता है। मल्टी-प्रोजेक्ट बिल्ड में यह बहुत ही सामान्य उपयोग का मामला है, लेकिन जैसे ही आपके पास बाहरी निर्भरता होती है।

प्लगइन दो कॉन्फ़िगरेशनों को उजागर करता है जिनका उपयोग निर्भरता घोषित करने के लिए किया जा सकता है: एपीआई और कार्यान्वयन। एपीआई कॉन्फ़िगरेशन का उपयोग निर्भरता को घोषित करने के लिए किया जाना चाहिए जो कि पुस्तकालय एपीआई द्वारा निर्यात किया जाता है, जबकि कार्यान्वयन कॉन्फ़िगरेशन का उपयोग उन निर्भरता को घोषित करने के लिए किया जाना चाहिए जो घटक के लिए आंतरिक हैं।

आगे की व्याख्या के लिए इस छवि को देखें।


आम आदमी के कार्यकाल में संक्षिप्त अंतर है:

  • यदि आप एक ऐसे इंटरफ़ेस या मॉड्यूल पर काम कर रहे हैं, जो आपके द्वारा बताई गई निर्भरता के सदस्यों को उजागर करके अन्य मॉड्यूल को सहायता प्रदान करता है, तो आपको 'एप' का उपयोग करना चाहिए।
  • यदि आप एक एप्लिकेशन या मॉड्यूल बना रहे हैं जो आंतरिक रूप से बताई गई निर्भरता को लागू करने या उपयोग करने जा रहा है, तो 'कार्यान्वयन' का उपयोग करें।
  • 'संकलन' ने 'एपीआई' के समान काम किया है, हालांकि, यदि आप केवल किसी पुस्तकालय का कार्यान्वयन या उपयोग कर रहे हैं, तो 'कार्यान्वयन' बेहतर काम करेगा और आपको संसाधनों को बचाएगा।

व्यापक उदाहरण के लिए @aldok द्वारा उत्तर पढ़ें।


संक्षिप्त समाधान:

बेहतर दृष्टिकोण implementation निर्भरता के साथ सभी compile निर्भरताओं को बदलने के लिए है। और केवल जहां आप एक मॉड्यूल का इंटरफ़ेस लीक करते हैं, आपको api उपयोग करना चाहिए। यह एक बहुत कम recompilation का कारण होना चाहिए।

 dependencies {
         implementation fileTree(dir: 'libs', include: ['*.jar'])

         implementation 'com.android.support:appcompat-v7:25.4.0'
         implementation 'com.android.support.constraint:constraint-layout:1.0.2'
         // …

         testImplementation 'junit:junit:4.12'
         androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
             exclude group: 'com.android.support', module: 'support-annotations'
         })
 }

अधिक समझाएं:

एंड्रॉइड ग्रैगल प्लगइन 3.0 से पहले : हमारे पास एक बड़ी समस्या थी जो एक कोड परिवर्तन के कारण सभी मॉड्यूल को फिर से जोड़ दिया जाता है। इसका मूल कारण यह है कि ग्रैडल को यह पता नहीं होता है कि आप किसी मॉड्यूल का इंटरफ़ेस दूसरे के माध्यम से लीक करते हैं या नहीं।

एंड्रॉइड ग्रैगल प्लगइन 3.0 के बाद : नवीनतम एंड्रॉइड ग्रैडल प्लगइन को अब आपको मॉड्यूल के इंटरफ़ेस को लीक करने के लिए स्पष्ट रूप से परिभाषित करने की आवश्यकता है। इसके आधार पर यह सही विकल्प बना सकता है कि इसे क्या करना चाहिए।

इस तरह के compile निर्भरता को दो नए लोगों द्वारा प्रतिस्थापित और प्रतिस्थापित किया गया है:

  • api : आप इस मॉड्यूल के इंटरफ़ेस को अपने स्वयं के इंटरफ़ेस के माध्यम से लीक करते हैं, जिसका अर्थ बिल्कुल पुराने compile निर्भरता के समान है

  • implementation : आप केवल इस मॉड्यूल का आंतरिक रूप से उपयोग करते हैं और इसे अपने इंटरफ़ेस के माध्यम से लीक नहीं करते हैं

तो अब आप स्पष्ट रूप से ग्रेड को एक मॉड्यूल को फिर से शुरू करने के लिए कह सकते हैं यदि एक प्रयुक्त मॉड्यूल का इंटरफ़ेस बदलता है या नहीं।

जेरेन मोल्स ब्लॉग के सौजन्य से






transitive-dependency