2015-12-21 13 views
27

वहाँ एक मॉड्यूल के build.gradle फ़ाइल के लिए एक यथोचित आसान तरीका दर्शाता है कि एक निर्भरता से कुछ फ़ाइलों बाहर रखा जाना चाहिए है? मैं विशेष रूप से एएआर से कुछ संसाधनों को छोड़ने में रूचि रखता हूं।एएआर निर्भरता से विशिष्ट संसाधनों को कैसे बाहर निकालना है?


LeakCanary मेमोरी लीक नीचे ट्रैक करने के लिए मदद करने के लिए एक दिलचस्प पुस्तकालय है। हालांकि, इसमें 21 या उच्चतर के compileSdkVersion की अनियंत्रित आवश्यकता है। हालांकि अधिकांश परियोजनाओं को इसमें कोई समस्या नहीं होनी चाहिए, लेकिन पुस्तकालय के लिए यह एक उचित कारण के बिना एक निश्चित compileSdkVersion की आवश्यकता नहीं है। एक डेवलपमेंट टीम ने अपने एप या कुछ के बड़े संस्करण अपडेट के हिस्से के रूप में केवल उन सेटिंग्स को बदलने के लिए सामान्य नीति के हिस्से के रूप में अपने compileSdkVersion को जमे हुए हो सकते हैं।

इस मामले में, कम से कम LeakCanary के v1.3.1 के लिए, एकमात्र कारण compileSdkVersion की आवश्यकता है, AFAICT है, क्योंकि आर एक res/values-v21/ निर्देशिका है, एक विषय परिभाषा यह है कि Theme.Material से विरासत हैं। इस विषय का प्रयोग नैदानिक ​​गतिविधि द्वारा किया जाता है। यह गतिविधि अंतिम उपयोगकर्ताओं द्वारा कभी नहीं देखी जाती है, केवल डेवलपर्स द्वारा debug बनाता है। स्पष्ट रूप से, वह गतिविधि क्या दिखती है, थीम-वार, वास्तव में कोई फर्क नहीं पड़ता। 21 के compileSdkVersion को मजबूर करना सिर्फ उस नैदानिक ​​गतिविधि के लिए एक निश्चित विषय है, आईएमएचओ, बेवकूफ।

यह अगर एक compile निर्देश हम कह सकते हैं के हिस्से के रूप "अरे, res/values-v21/ इस आर से छोड़ कृपया, m'kay?" अच्छा होगा। -v21 विषय बस कहीं और परिभाषित, -v21 विषय छोड़ने निर्माण को तोड़ने नहीं होगा या रनटाइम पर चीजों को तोड़ने के एक विषय का एक वैकल्पिक परिभाषा प्रदान कर रहा है, लेकिन केवल हमें एक Holo -themed नैदानिक ​​गतिविधि दे देंगे के बाद से।

मैं निर्भरता के साथ कैसे काम करता है this answer देखने के लिए असफल। मैं भी अनिश्चित if it is complete, and it certainly does not appear to be supported हूं। यह वास्तव में "सरल" — के रूप में योग्य नहीं है, मैं उम्मीद करता हूं कि किसी को build.gradle फ़ाइल में इसे छोड़ने की कोशिश न करें, केवल लीक कैनरी जैसे डायग्नोस्टिक लाइब्रेरी से एक फ़ाइल को ब्लॉक करने के लिए।

तो, वहाँ कुछ इस से अधिक आसान है कि Gradle के लिए Android प्लगइन का अब वर्तमान संस्करण के साथ काम करता है?

+0

मुझे लगता है, LeakCanary के लिए वैकल्पिक हल (https://github.com/square/leakcanary) होगा इसे फोर्क करें और अपने स्वयं के संस्करण को उचित 'compileSdkVersion' के साथ संकलित करें। मुझे यकीन नहीं है कि क्या इसे प्रश्न के उत्तर के रूप में गिना जा सकता है। –

+0

@KonstantinLoginov: LeakCanary परस्पर भागों चलती का एक उचित संख्या है, जिसके कारण मैं उलझन में है कि एक कांटा है कि सभी आसान हो जाएगा हूँ प्रतीत होता है। मैंने यह निर्धारित करने के लिए पर्याप्त पोकिंग किया कि केवल एंड्रॉइड 5.0+ फीचर 'थीम.मटेरियल' थी, जिसने मुझे इस सवाल से पूछा। जबकि मैं लीक कैनरी के संदर्भ में सवाल तैयार कर रहा हूं, यह मुद्दा उस पुस्तकालय से आगे निकलता है। – CommonsWare

+0

Google के वर्तमान ग्रेडल प्लगइन स्रोत सार्वजनिक होने पर यह अच्छा होगा। डीएसएल के स्रोत [1] के लिए टैग रिलीज टैग [2] के पीछे हैं। [1] https://android.googlesource.com/platform/tools/gradle/+refs [2] https://jcenter.bintray.com/com/android/tools/build/gradle/ – JBirdVegas

उत्तर

-3

हाँ, आप उपयोग कर सकते हैं Proguard

buildTypes { 
    release { 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 
     'proguard-rules.pro' 
    } 
debug { 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 
     'proguard-rules.pro' 
    } 
} 
+1

यह काम नहीं करेगा। –

11

संपादित करें:

लिखा आप के लिए उन्नत Gradle कार्य:

final List<String> exclusions = []; 

Dependency.metaClass.exclude = { String[] currentExclusions -> 
    currentExclusions.each { 
     exclusions.add("${getGroup()}/${getName()}/${getVersion()}/${it}") 
    } 
    return thisObject 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 
    compile ('com.android.support:appcompat-v7:20.+') 
    debugCompile ('com.squareup.leakcanary:leakcanary-android:1.3.1') 
      .exclude("res/values-v21/values-v21.xml") 
    releaseCompile ('com.squareup.leakcanary:leakcanary-android-no-op:1.3.1') 
} 

tasks.create("excludeTask") << { 
    exclusions.each { 
     File file = file("${buildDir}/intermediates/exploded-aar/${it}") 
     println("Excluding file " + file) 
     if (file.exists()) { 
      file.delete(); 
     } 
    } 
} 

tasks.whenTaskAdded({ 
    if (it.name.matches(/^process.*Resources$/)) { 
     it.dependsOn excludeTask 
    } 
}) 

अब आप प्रत्येक निर्भरता पर विधि .exclude() उपयोग कर सकते हैं प्रदान पथों की सूची में, आप निर्दिष्ट निर्भरता से बाहर निकलना चाहते हैं। इसके अलावा, आप .exclude() विधि कॉल को ढेर कर सकते हैं।

+0

मुझे लगता है कि आपकी 'LEAKCANARY_ARTIFACT_NOOP' परिभाषा में एक बग है। और यह दिलचस्प है, लेकिन यह वास्तविक प्रश्न का उत्तर नहीं देता है: "क्या मॉड्यूल की 'build.gradle' फ़ाइल के लिए एक उचित तरीका है यह इंगित करने के लिए कि निर्भरता से कुछ फाइलों को बाहर रखा जाना चाहिए?" यह मेरे उदाहरण परिदृश्य को एक वैकल्पिक फैशन (संसाधनों को संशोधित करने) में संबोधित करता है। हालांकि धन्यवाद! – CommonsWare

+0

मुझे नहीं लगता कि बॉक्स से बाहर निकलने के लिए कोई भी तरीका है। लेकिन आप अपना खुद का कार्य लिख सकते हैं, इस तरह, संसाधन संसाधन विलय से पहले निष्पादित किया जाएगा और उन संसाधनों को हटा देगा जिन्हें आपको आवश्यकता नहीं है। प्रत्येक आयर मॉड्यूल के सभी संसाधन बिल्ड/विस्फोट-एआर निर्देशिका में संग्रहीत होते हैं, और आप उन्हें वहां से सुरक्षित रूप से हटा सकते हैं और उन्हें बिल्कुल संसाधित नहीं किया जाएगा। हालांकि, सादगी के बारे में: आप "संकलन" बंद करने के लिए अपना स्वयं का रैपर लिख सकते हैं जो कार्य/बहिष्कारों की सरणी ले सकता है जिसे कार्य में शामिल किया जाएगा। मैं इसे कल बनाने की कोशिश करूंगा। – IlyaGulya

+0

उत्तर संपादित किया गया। अब छोड़ना बहुत आसान है, मुझे लगता है। – IlyaGulya

0

मेरा मानना ​​है कि आप एंड्रॉयड Gradle प्लगइन डीएसएल के PackagingOptions सुविधा का उपयोग कर अधिक सुंदर ढंग से इस समस्या का समाधान कर सकते हैं।

मैं इस अपने आप को कुछ देशी पुस्तकालयों मैं अपने प्रोजेक्ट में एक आर द्वारा शुरू की जरूरत नहीं थी बाहर करने के लिए उपयोग करने के लिए कर रहा था।

android { 
    ... 
    packagingOptions { 
     exclude '/lib/armeabi-v7a/<file_to_exclude>' 
    } 
} 

मामले सवाल में उल्लिखित के लिए, मेरा मानना ​​है कि यह काम करेगा:

android { 
    ... 
    packagingOptions { 
     exclude '/res/values-v21/<file_to_exclude>' 
    } 
} 
+1

मैं इसे कभी-कभी कोशिश करूंगा, लेकिन मुझे संदेह है कि यह काम करेगा। सबसे पहले, निर्माण प्रक्रिया में 'pacakgingOptions' बहुत देर हो चुकी है - निर्माण होने से पहले' compileSdkVersion' के कारण निर्माण विफल होना चाहिए। दूसरा, AFAIK, 'पैकेजिंग ऑप्शन' एपीके में कहां स्थित हैं, इस पर आधारित चीजों को छोड़कर संदर्भित कर रहा है, और एक्सएमएल संसाधन सामान्य फाइलों के रूप में एपीके में नहीं जाते हैं। हालांकि धन्यवाद! – CommonsWare

+0

गतिशील रूप से ऐसा करने का कोई मौका? https://stackoverflow.com/questions/46543271/how-to-exclude-files-from-aar-with-gradle-dynamically – 4ntoine

संबंधित मुद्दे

 संबंधित मुद्दे