2012-08-31 13 views
22

हमारे तरीकों में से एक में, हम सूची दृश्य में चिकनी स्क्रॉलिंग का उपयोग नहीं करते हैं। चूंकि यह विधि API स्तर 8 (FROYO) से पहले उपलब्ध नहीं है, इसलिए हमने पिछले एसडीके संस्करणों में विधि को कॉल करने से रोकने के लिए TargetApi एनोटेशन का उपयोग किया था।लक्ष्य एपीआई

जैसा कि आप देख सकते हैं, हम क्लास परिभाषा में और कक्षाओं की वस्तुओं का उपयोग करने वाले बयानों में लक्ष्यएपी एनोटेशन का उपयोग करते हैं। यह आवश्यक से अधिक है।

हमारी समस्या यह है कि लक्ष्य एपीआई एनोटेशन को ध्यान में नहीं रखा जाता है और संस्करण ईसीएलआईआर (एसडीके 7) में हमारे एमुलेटर दुर्घटनाग्रस्त हो जाता है। ट्रेसिंग करके, हम केवल यह महसूस करते हैं कि केवल संस्करण 8+ में निष्पादित किया जाना चाहिए कोड को संस्करण 7 में भी निष्पादित किया जाना चाहिए।

क्या हमें कुछ याद आ रहा है?

इस कोड को एक श्रोता में है:

@TargetApi(8) 
private final class MyOnMenuExpandListener implements OnMenuExpandListener { 
    @Override 
    public void onMenuExpanded(int position) { 
     doScrollIfNeeded(position); 
    } 

    @Override 
    public void onMenuCollapsed(int position) { 
     doScrollIfNeeded(position); 
    } 

    protected void doScrollIfNeeded(int position) { 
     if (mListViewDocuments.getLastVisiblePosition() - 2 < position) { 
      mListViewDocuments.smoothScrollToPosition(position + 1); 
     } 
    } 
} 

और श्रोता इस तरह से पंजीकृत है:

@TargetApi(8) 
private void allowSmothScrollIfSupported() { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { 
     //This if should not be necessary with annotation but it is not taken into account by emulator 
     Log.d(LOG_TAG, "Smooth scroll support installed."); 
     folderContentAdapter.setOnMenuExpandListener(new MyOnMenuExpandListener()); 
    } 
} 

BTW, हम डिबग मोड में कोड चलाने के लिए, तो समस्या से संबंधित नहीं है obotuscation एनोटेशन को हटा रहा है।

+3

बीटीडब्ल्यू, आप '@TargetApi (Build.VERSION_CODES.FROYO)' 'TargetApi (8) 'के बजाय' @TargetApi (Build.VERSION_CODES.FROYO) लिख सकते हैं। – Wyzard

+0

आप सही हैं। और इसके लिए आपका लक्ष्य एसडीके जितना संभव हो उतना उच्च होना चाहिए। – Snicolas

उत्तर

50

@TargetApi किसी भी कोड को चलाने से नहीं रोकता है, यह केवल कोड को एनोटेट करने और नए एपीआई के लिए कंपाइलर त्रुटियों को रोकने के लिए है जब आप जानते हैं कि आप केवल उन्हें सशर्त रूप से बुला रहे हैं।

तुम अब भी

if (Build.VERSION.SDK_INT > 7){ 
    //... 
} 
+1

यह सब लिंट त्रुटियों को हटा देता है। [यहां] जांचें (http://tools.android.com/recent/lintapicheckhttp://tools.android.com/recent/lintapicheck) – nandeesh

+0

वास्तव में? ऐसा लगता है। लेकिन यह वास्तव में अजीब लगता है कि @SuppressWarnings की बजाय एक अलग प्रणाली है क्योंकि हम आमतौर पर लिंट त्रुटियों को रोकने के लिए करते हैं। – Snicolas

+0

वास्तव में, यह एनोटेशन का एक और रूप है और प्रोग्रामेटिक विधि जो चल रहा है उसके अच्छे नियंत्रण की अनुमति देती है। – Guykun

5

की तर्ज पर कुछ जोड़ने के लिए इस बारे में अधिक सोच के लगभग एक वर्ष के साथ की जरूरत है, मैं @Guykun के जवाब देने के लिए एक छोटे से पूरक जोड़ना चाहते हैं:

@TargetApi का उपयोग केवल डेवलपर्स कहने के लिए किया जाएगा "अरे, XXX एंड्रॉइड एसडीके के नीचे इस विधि का उपयोग न करें"। आमतौर पर लिंट।

तो, अगर आप की तरह एक विधि डिजाइन:

if (Build.VERSION.SDK_INT > 7){ 
    //... 
} 

तो आप @TargetApi (7) अपने विधि के हस्ताक्षर में जोड़ना चाहिए।

लेकिन, यदि आप एक और को बयान जोड़ने के लिए, और एक वैकल्पिक ऐसा एंड्रॉयड के सभी संस्करणों के लिए काम करता है कि प्रदान करते हैं:

if (Build.VERSION.SDK_INT > 7){ 
    //... 
} else { 
    //... 
} 

तो आप नहीं @TargetApi जोड़ना चाहिए (7) अपनी विधि के हस्ताक्षर के लिए। अन्यथा, अन्य डेवलपर्स सोचेंगे कि वे आपके विधि बेल्व एपीआई स्तर 7 का उपयोग नहीं कर सकते हैं, लेकिन वास्तव में, यह उनके लिए भी काम करेगा।

इसलिए इस एनोटेशन का उपयोग स्थिर विश्लेषण के लिए, विधि द्वारा समर्थित न्यूनतम एपीआई स्तर को इंगित करने के लिए किया जाना चाहिए। जैसा कि:

@TargetApi(7) 
public void foo() { 
    if (Build.VERSION.SDK_INT > 7){ 
     //... 
    else if (Build.VERSION.SDK_INT > 10){ 
     //... 
    } 
} 

और इससे भी बेहतर, android.Build.VERSION_CODES.* में परिभाषित स्थिरांक का उपयोग करें।

बीटीडब्लू, आपने देखा होगा कि स्वच्छ क्लीनर कोड को छोड़कर और भविष्य में सार्वजनिक तरीके को बढ़ावा देने में मदद करने के अलावा, यह वास्तव में निजी तरीकों के लिए बेकार है।

+0

यह @Tom के प्रश्न का उत्तर है। – Snicolas

+0

मैं आप की तरह लगता होगा, लेकिन यहाँ से एंड्रॉयड स्टूडियो के LoginActivity विज़ार्ड उत्पन्न कोड से एक अंश है: '@TargetApi (Build.VERSION_CODES.HONEYCOMB_MR2) निजी शून्य showProgress (अंतिम बूलियन शो) { अगर (Build.VERSION। SDK_INT> = Build.VERSION_CODES.HONEYCOMB_MR2) { // ... } else { // ... } } ' – nicobo

+0

बस चीजों को और अधिक स्पष्ट है, शायद .. – Snicolas

1

जब एक विधि से अधिक API स्तर की ओर लक्षित का उपयोग कर फाहा त्रुटि को लागू करने के लिए आपको TargetApi के बजाय RequiresApi उपयोग कर सकते हैं और आप संस्करण कोड की जाँच के बिना विधि का उपयोग करने की कोशिश करेंगे, जब भी, आप संकलन त्रुटि मिल जाएगा।

यह वही है documentation कहते हैं के बारे में RequiresApi

यह पुराने @TargetApi एनोटेशन के उद्देश्य में समान है, लेकिन अधिक स्पष्ट रूप से व्यक्त करता है, बल्कि करने के लिए इस्तेमाल किया जा रहा है कि इस से फोन करने वाले पर एक आवश्यकता है है विधि के भीतर "दबाने" चेतावनियां minSdkVersion से अधिक है।

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