2012-03-23 21 views
9

एक गैर सार्वजनिक एपीआई है जिसे मुझे एंड्रॉइड के वेबव्यू के साथ एक क्विर्क को काम करने के लिए ओवरराइड करने की आवश्यकता है।क्या मैं एक छिपी हुई (लेकिन सार्वजनिक) विधि को ओवरराइड कर सकता हूं और इसकी सुपर विधि कह सकता हूं?

एपीआई छिपा हुआ है, लेकिन यह सार्वजनिक है:

/** 
* ... 
* 
* @hide pending API council approval 
*/ 
public boolean selectText() { 
    ... 
} 

तो मैं यह बस अपने ही WebView कक्षा में यह घोषणा करके ओवरराइड कर सकते हैं, शून्य से @Override:

public boolean selectText() { 
    ... 
} 

क्या यह संभव है मेरे ओवरराइड से सुपर विधि को कॉल करने के लिए? आम तौर पर मैं लिख सकते हैं:

public boolean selectText() { 
    return super.selectText(); 
} 

लेकिन प्रक्रिया गुप्त रखी है, इसलिए super.selectText() उपलब्ध नहीं है। अगर मैं प्रतिबिंब का उपयोग करता हूं:

public boolean selectText() { 
    return (Boolean) WebView.class.getMethod("selectText").invoke(this, (Object[]) null); 
} 

मुझे एक अनंत लूप मिलता है क्योंकि यह मेरी ओवरराइड विधि को कॉल करता है।

क्या इस विधि को ओवरराइड करने और सुपर विधि को कॉल करने में सक्षम होने के लिए वैसे भी है?

धन्यवाद!

+0

नहीं। AFAIK यह संभव नहीं है। – kosa

+1

देखें http://stackoverflow.com/questions/5411434/how-to-call-a-superclass-method-using-java-reflection और http://stackoverflow.com/questions/2100412/java-reflection-accessing- विधि-साथ-डिफ़ॉल्ट-संशोधक-इन-द-सुपर-क्लास और http://stackoverflow.com/questions/9771933/invoking-super-class-method-without-its-instance-using- कुछ विचारों के लिए प्रतिबिंब – CommonsWare

+0

है विधि को ओवरराइड करना बिल्कुल जरूरी है? क्यों नहीं अपनी विधि 'doSelectText() 'को कॉल करें, और उसके बाद' selectText() 'को कॉल करने के लिए प्रतिबिंब का उपयोग करें? –

उत्तर

3

वहाँ वैसे भी इस विधि को ओवरराइड और सुपर विधि कॉल करने में सक्षम होना है?

नहीं, दुर्भाग्यवश, जैसा कि How to call a superclass method using Java reflection प्रश्न के उत्तर में समझाया गया है, आप इस समस्या को प्रतिबिंब के साथ हल नहीं कर सकते हैं।

+0

मैं सहमत नहीं हूं - मेरा जवाब देखें – ceph3us

1

वास्तव में कुछ तरीके यह करने के लिए कर रहे हैं, लेकिन वे एक छोटे से श्रम गहन हैं, तो शायद एक अंतिम उपाय के रूप में इस्तेमाल किया जाना चाहिए। जड़ वाले डिवाइस के साथ, आप डिवाइस पर फ्रेमवर्क जार से प्रतीकों को निकाल सकते हैं और उन्हें अपने एसडीके/प्लेटफॉर्म/फ़ोल्डर में android.jar में डाल सकते हैं। ऐसा करने के लिए एक स्क्रिप्ट के लिए प्रयुक्त होता है; नौकरी स्विच करने में इसे खो दिया। स्मृति से

कदम (ध्यान दें कि आप शायद मुसीबत होगा के रूप में मैं कदम याद नहीं है ... उन्नत उपयोगकर्ताओं को, जो समझते हैं कि मैं कम से प्राप्त करने के लिए कोशिश कर रहा हूँ के लिए):

  • adb pull/प्रणाली/ढांचे/* (ये सभी जार फाइलें हैं)। यह framework.jar करने के लिए पर्याप्त हो सकता है। उन्हें अनजिप करें।
  • हर एक मेरा मानना ​​है कि आप एक classes.dex और एक प्रकट दे देंगे के लिए
  • । तुम सिर्फ वर्ग फ़ाइलों मिलता है , अगले कदम के
  • classes.dex dex2jar और classes_dex2jar.jar या जो कुछ भी उत्पादन dex2jar से है unjar, जो आप .class फ़ाइलों
  • लेने का एक समूह को छोड़ दे देंगे वर्ग फ़ाइलों और अपने Android SDK के लिए android.jar फ़ाइल उन्हें जोड़ने (SDK/प्लेटफार्मों/android- # एसडीके #/android.jar)।

मैं एक android-1 # एसडीके # फ़ोल्डर में अपने android- # एसडीके # फ़ोल्डर डुप्लिकेट करने का सुझाव देते हैं, तो एंड्रॉयड -19 हो जाता है एंड्रॉयड -119, और फिर ro.build कहने के लिए फ़ोल्डर में build.prop बदल जाते हैं। version.sdk = 119, और फिर एसडीके 119. के खिलाफ इस तरह आप एक साफ 119 या के खिलाफ इमारत का विकल्प है निर्माण अपने 119. काट दिया बस किसी भी com.android.internal.R फ़ाइलों का उल्लेख नहीं है, क्योंकि उन आईडी नहीं हैं मेरे अनुभव में सटीक।

अब आप इन प्रतीकों के खिलाफ संकलन और उन्हें ठीक उपयोग करने में सक्षम हो जाएगा। यद्यपि वे पागल नहीं होते हैं, अगर वे बदलते हैं कि चीजें कैसे काम करती हैं, और उनके पास तीसरे पक्ष के ऐप्स के साथ संगतता बनाए रखने का कोई दायित्व नहीं है।

यह काम करता है क्योंकि छिपाने टैग केवल एसडीके संकलन चरण के दौरान इस्तेमाल किया और अपने SDK में स्थित android.jar से इन प्रतीकों स्ट्रिप्स है। अगर हम सभी प्रतीकों कि डिवाइस पर संकलित किए जाते हैं इकट्ठा करेंगे और उन्हें अपने एसडीके जार में रहना है, यह है कि वे कभी नहीं छीन रहे थे।

वैकल्पिक रूप से आप खींच सकते हैं और पूर्ण एंड्रॉइड पेड़ (https://source.android.com/source/building.html) का निर्माण कर सकते हैं और फिर पूर्ण स्रोत के खिलाफ अपना ऐप बना सकते हैं, जो पहला कदम अनिवार्य रूप से पहले से संकलित प्रतीकों को ले कर और उनके साथ काम कर रहा है।

0
  1. हाँ आप कर सकते हैं :) - प्रश्न के पहले भाग
  2. नहीं आप कर सकते हैं नहीं - दूसरा एक

समाधान 1) - सबसे अच्छा तुम यहाँ निकटतम क्या कर सकते हैं जो आप प्राप्त करना चाहते हैं

// to override method 
// which IDE doesn't see - those that contains {@ hide} text in JavaDoc 
// simple create method with same signature 
// but remove annotation 
// as we don't know if method will be present or not in super class 
// 
//@Override  
public boolean callMethod(String arg) { 

    // can we do it ? 
    // boolean result = super.callMethod(arg) 
    // no why ? 
    // You may think you could perhaps 
    // use reflection and call specific superclass method 
    // on a subclass instance. 


/** 
* If the underlying method is an instance method, it is 
* invoked using dynamic method lookup as documented in The 
* Java Language Specification, Second Edition, section 
* 15.12.4.4; in particular, overriding based on the runtime 
* type of the target object will occur. 
*/ 


    // but always you can see what super class is doing in its method 
    // and do the same by forward call in this method to newly created one 
    // return modified result 
    return doSomthingWhatSuperDo() 
} 

समाधान 2)

वस्तु (जो इस विधि कॉल) आप के अंतर्गत आता है करता है? और इंटरफ़ेस लागू करता है?

यदि ऐसा है तो कैसे प्रॉक्सी के बारे में?

  1. वर्ग का विस्तार
  2. प्रॉक्सी
  3. उपयोग प्रॉक्सी
  4. अवरोधन विधि कॉल
  5. कुछ शर्तों के आधार पर बनाने के? अपने कार्यान्वयन को कॉल करें या मूल रूप से वापस आते हैं?
संबंधित मुद्दे

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