2014-07-23 6 views
5

से जावा जावा विधियों को ध्यान में रखते हुए मैं प्रोगार्ड के माध्यम से एक एंड्रॉइड ऐप कोड को खराब करने की कोशिश कर रहा हूं। प्रोगार्ड के साथ प्रसंस्करण के बाद ऐप स्वयं ही काम कर रहा है, हालांकि सी से जावा तक की मूल कॉल java.lang.NoSuchMethodError से विफल हो रही है।एंड्रॉइड जेएनआई

इस कोड को देशी हिस्सा है, जहां एक फोन जावा वर्ग उदाहरण के लिए किया जाता है, EngineStarted नामित से है:

void callEngineStarted(JNIEnv* env, bool isStreamOne) 
{ 
    jclass cls; 
    if(isStreamOne == true) { 
     cls = (*env)->GetObjectClass(env, currentObjectOne); 
    } else { 
     cls = (*env)->GetObjectClass(env, currentObjectTwo); 
    } 

    jmethodID midCallBack = (*env)->GetMethodID(env, cls, "EngineStarted", "(I)V"); 
    if (0 == midCallBack) { 
     LOGW("Could not find EngineStarted method in class"); 
     return; 
    } 

    if(isStreamOne == true) { 
     (*env)->CallVoidMethod(env, currentObjectOne, midCallBack, 1); 
    } else { 
     (*env)->CallVoidMethod(env, currentObjectTwo, midCallBack, 0); 
    } 
} 

जावा इस पद्धति है। इसे केवल मूल भाग से ही जाना जाता है, और कहीं और नहीं। उस वजह से, प्रोजेर्ड विधि को हटा रहा है।

public void EngineStarted (int isStreamOne) 
    { 
    Log.v("decoderService", "PDecoder - Engine started, using stream " + (isStreamOne == 1 ? "one" : "two")); 
    this.isStreamOne = isStreamOne == 1; 

    // Initialize the player 
    InitializePlayer(isStreamOne); 
    } 

मैंने इसे proguard-project.txt में जोड़ने का प्रयास किया है, लेकिन समस्या का समाधान नहीं किया।

-keep class com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative { 
    void EngineStarted(int); 
    void PositionChanged(int); 
    void SetDuration(int); 
    void Completed(); 
    void CompletedWithFade(); 
    void Spectrum (***); 
} 

संकलन के बाद, mapping.txt में विधियों को शामिल नहीं किया गया है, मुझे संदेह है कि प्रोगार्ड उन्हें हटा देता है। मैं इन विधियों को हटाया जा सकता हूं और/या नाम बदल सकता हूं?

संपादित करें/समाधान:

मैं एक वाइल्डकार्ड के साथ पूर्ण स्थान बदलकर समस्या को हल करने में सक्षम था। इसने कुछ तरीकों को बचाया लेकिन पर्याप्त नहीं था। पता नहीं क्यों एक और विधि (void InitializePlayer(int)) जिसे डंप किए गए लोगों द्वारा बुलाया गया था, को भी डंप किया गया था जिसने किसी भी तरह से चेन रिएक्शन बनाया था। इस विधि को जोड़ने से शेष गायब विधियों को हल किया गया। अंतिम समाधान हो गया

-keepclassmembers class **.PDecoderNative { 
    native <methods>; 
    void InitializePlayer(int); 
    void EngineStarted(int); 
    void PositionChanged(int); 
    void SetDuration(int); 
    void Completed(); 
    void CompletedWithFade(); 
    void Spectrum(float[]); 
} 

संपादित करें: समस्या ProGuard साथ नहीं था, लेकिन ProGuard साथ समय-समय पर project.txt फ़ाइल पढ़ने में सक्षम नहीं किया जा रहा। पूरी परियोजना को डिस्क पर एक नए स्थान पर ले जाया गया और फ़ाइल को फिर से बनाया गया। यह पूरी तरह से काम कर रहा है।

+0

शायद यह विधि नाम बदलने वाले प्रोगार्ड के कारण है। 1 या अधिक तरीकों के लिए अनुकूलन को छोड़ने का एक विकल्प है, उपयोग के तहत मैन्युअल में [Keep] (http://proguard.sourceforge.net/index.html#manual/usage.html) विकल्प देखें> रखें। –

+0

आप बदले गए नामों को mapping.txt पर लॉग कर सकते हैं, जो एक डिफ़ॉल्ट व्यवहार है। 'PDecoderNative getPrevious() -> e' जैसी ही चीजें हैं, फिर भी जिन तरीकों का मैंने उल्लेख किया है वे लॉग में दिखाई नहीं देते हैं। – emrahgunduz

उत्तर

3

आपका विश्लेषण सही है और आपकी कॉन्फ़िगरेशन भी सही दिखती है। आपको अपनी कक्षा के पूर्ण-योग्य नाम (com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative) को दोबारा जांचना चाहिए। ध्यान दें कि आपको '।' के बजाय '$' का उपयोग करना होगा। लागू होने पर, आंतरिक कक्षाओं को अलग करने के लिए।

यदि आपने सही नाम निर्दिष्ट किए हैं, तो आप उन्हें फ़ाइल प्रोगार्ड/seed.txt में देखेंगे जो ProGuard एंड्रॉइड बिल्ड प्रक्रिया में लिखता है।

एक बार यह काम करता है, तो आप -keepclassmembers द्वारा प्रतिस्थापित कर सकते हैं। ProGuard तब भी विधि नाम रखेगा लेकिन कक्षा के नाम को खराब कर देगा, जो इस मामले में ठीक है।

+0

उत्तर के लिए धन्यवाद। मैंने कक्षा के नाम की जांच की, यह ठीक था। डंप किए गए कॉलबैक विधियों के साथ use.txt में भी वही नाम दिखाई देता है। मुझे नहीं पता कि क्यों कक्षा के नाम का पूरा उपयोग परिणाम विधियों के डंप में होता है। हालांकि नाम को ** में बदलना। PDecoderNative ने समस्या हल की। मैं आपके उत्तर को सही के रूप में स्वीकार करूंगा क्योंकि मैंने आपके नाम/पैकेज सुझाव के माध्यम से समस्या को हल करने में कामयाब रहे। – emrahgunduz

+0

मैं कल्पना नहीं कर सकता कि ProGuard क्लासिक नाम को बिना जंगली कार्ड के गलत तरीके से पार्स करेगा।दोबारा जांचने के लिए, आप इसे proguard/seed.txt से dexguard-project.txt में कॉपी/पेस्ट करने का प्रयास कर सकते हैं। आपको प्रोजेवार्ड/seed.txt में रखा गया विधि नाम भी देखना चाहिए। –

+0

अनुमान लगाएं, मैंने वाइल्डकार्ड का उपयोग करके बदलने के बाद भी वही समस्या शुरू कर दी। प्रोजेक्ट फ़ोल्डर को हटाया और शून्य से project.txt फ़ाइल को फिर से बनाया। अब यह वाइल्डकार्ड के बिना काम करता है। संभवतः फ़ाइल लॉक हो गई है या दूषित हो गई है, या कुछ सुरक्षा समस्या समय-समय पर प्रोजेवार्ड को फ़ाइल को पढ़ने नहीं दे रही है। मुझे लगता है कि एसडीके या मैकोक्स पर आखिरी अपडेट मेरे साथ गड़बड़ कर रहा था। – emrahgunduz

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