2011-10-02 13 views
6

मैं Android बाज़ार पर एक आवेदन पत्र वितरित किया जाता है। मुझे कुछ छोटे उपयोगकर्ताओं (शायद 2%) से त्रुटि रिपोर्ट वापस मिल रही हैं, जहां उन्हें NullPointerExceptions मिल रहे हैं जहां यह तार्किक अर्थ नहीं बनाता है।एंड्रॉयड ProGuard समझ से परे कोड NullPointerException के कारण जब यह वास्तव में नहीं होना चाहिए

मैं इस अपने आप को दोहराने में सक्षम कभी नहीं किया गया है। कोड अपेक्षाकृत सरल है और एक सामान्य कोड पथ है जिसे प्रत्येक उपयोगकर्ता को पालन करना होता है। मैं वास्तव में कोड कि संभवतः एनपीई बनाने जा सकता है और एक कोशिश पकड़ ब्लॉक में लपेटा और एक कस्टम क्रम अपवाद के हर अलग लाइन कर लिया है, लेकिन मैं अभी भी पकड़ा नहीं NullPointerException त्रुटियों हो रही है।

इस बिंदु पर, केवल एक चीज मैं कल्पना कर सकते हैं यह होगा मेरी Proguard कहानियो से संबंधित कुछ है। मैंने कुछ अन्य आलेख देखा है - अगर आप अजीब व्यवहार देखते हैं, लेकिन जहां तक ​​मैं कह सकता हूं, मैं उस विकल्प का उपयोग नहीं कर रहा हूं।

किसी और अनुभवी रहस्यमय NPEs एंड्रॉयड और ProGuard का उपयोग करके किया है। क्या ऐसी कोई अन्य सेटिंग्स है जो लोग इस समस्या के कारण हो रहे अनुकूलन को डायल करने के लिए अनुशंसा कर सकते हैं?

कोई अन्य विचार?

public MainMenuScreen(final HauntedCarnival game) { 
    super(game); 

    game.startMusic("data/music/intro.mp3"); 

    stage = new Stage(Screen.SCREEN_WIDTH, Screen.SCREEN_HEIGHT,true); 
    stage.addActor(new Image("background", Assets.mainMenuBackground)); 
    Image title = new Image("title", Assets.mainMenuTitle); 
    title.x = 0; 
    title.y = 340; 
    resetEyeBlink(); 
    stage.addActor(title); 
    dispatcher.registerInputProcessor(stage); 
    settings = game.getSettings(); 

    eyeBlinkImage = new Image("eyeBlink", Assets.eyeBlink); 
    if (settings.getPlayers().isEmpty()) { 
     settings.addPlayer("Player One"); 
     settings.save(game); 
    } 
    setupContinue(); 


} 

तो केवल संभावनाओं मैं खेल, डिस्पैचर और सेटिंग्स हैं देख सकते हैं:

संदर्भ के लिए, सुलझे समारोह है कि एनपीई हो रही है है।

खेल अन्य वर्ग में इस कोड के माध्यम से सेट हो जाता है। गेम उस अन्य वर्ग में एक अंतिम चर है:

game.setScreen(new MainMenuScreen(game)); 

प्रेषक सुपर ऊपर कॉल में प्रवेश के भीतर सेट हो जाता है।

getSettings() एक सेटिंग ऑब्जेक्ट देता है जो एप्लिकेशन की शुरुआत में सेट हो जाता है, निजी है और कभी भी परेशान नहीं होता है। यह कई बार इस विधि से पहले भी इस्तेमाल किया जाता है।

ऑटो-मुक्केबाजी प्राइमेटिव नहीं हैं।

-optimizationpasses 5 
-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 

-keepattributes Signature 

-keep public class com.alkilabs.hauntedcarnival.settings.Settings 
-keep public class com.alkilabs.hauntedcarnival.settings.Settings { 
    *; 
} 
-keep public class com.alkilabs.hauntedcarnival.settings.Player 
-keep public class com.alkilabs.hauntedcarnival.settings.Player { 
    *; 
} 
-keepnames public class com.alkilabs.hauntedcarnival.world.World 
-keepnames public class * extends com.alkilabs.hauntedcarnival.world.upgrades.Upgrade 
-keepnames public class * extends com.alkilabs.hauntedcarnival.world.achievments.Achievement 

-keepnames public class com.alkilabs.hauntedcarnival.world.monsters.MonsterType 
-keepclassmembers class * extends com.alkilabs.hauntedcarnival.world.monsters.Monster { 
    public <init>(com.alkilabs.hauntedcarnival.world.monsters.MonsterType, java.lang.Integer, com.alkilabs.hauntedcarnival.world.World); 
} 

-keepnames public class com.alkilabs.hauntedcarnival.world.items.ItemType 
-keepclassmembers class * extends com.alkilabs.hauntedcarnival.world.items.Item { 
    public <init>(com.alkilabs.hauntedcarnival.world.World, java.lang.Integer, java.lang.Integer); 
} 


-keep public class * extends android.app.Activity 
-keep public class * extends android.app.Application 
-keep public class * extends android.app.Service 
-keep public class * extends android.content.BroadcastReceiver 
-keep public class * extends android.content.ContentProvider 
-keep public class * extends android.app.backup.BackupAgentHelper 
-keep public class * extends android.preference.Preference 

-dontwarn com.badlogic.gdx.scenes.scene2d.ui.utils.DesktopClipboard 
-dontwarn com.badlogic.gdx.utils.JsonWriter 
-dontwarn com.badlogic.gdx.utils.XmlWriter 

-keepclasseswithmembernames class * { 
    native <methods>; 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

-keepclassmembers class * extends android.app.Activity { 
    public void *(android.view.View); 
} 

-keepclassmembers enum * { 
    public static **[] values(); 
    public static ** valueOf(java.lang.String); 
} 

-keep class * implements android.os.Parcelable { 
    public static final android.os.Parcelable$Creator *; 
} 
+0

क्या आप कोड पोस्ट कर सकते हैं जो आपके द्वारा उपयोग की जाने वाली एनपीई और प्रोगार्ड सेटिंग्स का कारण बनता है? – Idolon

+0

मैंने विशिष्ट कोड और मेरे प्रोगार्ड कॉन्फ़िगरेशन – Paul

उत्तर

2

आपका सबसे अच्छा शर्त mapping.txt फ़ाइल और retrace उपकरण का उपयोग करने के लिए त्रुटि के सटीक स्थान को खोजने के लिए होगा:

यहाँ ProGuard config है। वहां से यह समझना आसान होगा कि यह वास्तव में प्रोगार्ड या कुछ अन्य अंत-मामले है जिसे आपने नहीं सोचा था।

ऐसा करने के लिए, यदि आप किसी अन्य फाइल करने के लिए डेवलपर के कंसोल से स्टैक ट्रेस कॉपी करने की जरूरत है, चलो यह

कहा जाता है मान लें c: \ trace.txt

अब, में अपनी परियोजना , आपको 4 फाइलों के साथ एक प्रोगगार्ड फ़ोल्डर मिलेगा। मान लेते हैं अपनी परियोजना है चलो में

c: \ परियोजना

आपको बस इतना करना retrace उपकरण (करने के लिए परिवर्तन पर स्थित चलाया जाता है (आसान उपयोग के लिए बैच फ़ाइल का प्रयोग करके) की आवश्यकता होगी क्या अपने Android SDK फ़ोल्डर का स्थान):

c: \ Android-SDK-windows \ उपकरण \ ProGuard \ बिन \ retrace.bat

उस फ़ोल्डर में जाओ और चलाएँ:

retrace c: \ परियोजना \ ProGuard \ mapping.txt c: \ trace.txt

वहाँ से, यह हमारे सटीक आंकड़ा बहुत आसान होता अपवाद की रेखा और शायद त्रुटि को खोजने के लिए।

मेरे अनुभव से, केवल एक चीज जो गड़बड़ हो सकती है वह तीसरे पक्ष के पुस्तकालय हैं। मेरी सभी परियोजनाओं के लिए सामान्य एंड्रॉइड कोड, कभी भी obfuscation से नुकसान नहीं पहुंचा था।

+0

के बारे में अधिक जानकारी दी है हां मैंने पहले ही ऐसा कर लिया है। मुझे सटीक विधि और पूरे स्टैक ट्रेस पता है जिसे उस विधि कहा जाता है। केवल एक चीज जो मुझे नहीं पता वह लाइन नंबर है लेकिन ऐसा इसलिए है क्योंकि यह लाइन संख्याओं के बिना उत्पादन रिलीज है। साथ ही, जो मैं समझता हूं, प्रोगुआर्ड वास्तव में अपने अनुकूलन चरण के दौरान आपके कुछ कोड को फिर से लिखता है (जो कि मुझे प्रोजेक्ट पर शक करने का एक कारण है)। इसलिए मुझे प्रत्येक पंक्ति के पुराने फैशन डिबगिंग के लिए भेजा गया था जो एनपीई उत्पन्न कर सकता था, लेकिन हां, कोई पासा नहीं था। – Paul

+0

तो मेरे लिए एकमात्र सलाह है कि आप कुछ दिनों तक एक unobfuscated संस्करण डालें और देखें कि आपको अतिरिक्त त्रुटि रिपोर्ट मिलती है या नहीं ...मुझे अपने कोड में प्रोजेवार्ड के साथ त्रुटियों का सामना नहीं हुआ (सबसे जटिल ऐप्स से सबसे सरल लोगों तक) और मैं हमेशा अपनी परियोजनाओं को खराब करता हूं। – IncrediApp

+0

हाँ, मुझे चिंता थी कि उसे उस पर आना पड़ सकता है, लेकिन दुर्भाग्यवश मैं अपने कोड को जंगली में देखने के लिए नहीं जा रहा हूं। मैंने कुछ अन्य पोस्ट मोबाइल फोन पर प्रोग्रार्ड कोड के साथ मुद्दों के बारे में बात की है: http://stackoverflow.com/questions/93290/best-java-obfuscation-plplication-for-size-reduction इसलिए मुझे नहीं लगता कि यह अभूतपूर्व है । मैं बस उम्मीद कर रहा था कि अन्य लोगों की समान परिस्थितियां हो सकती हैं। – Paul

1

क्षमा करें मैं अभी तक टिप्पणी पोस्ट नहीं कर सकता (मैं SO के लिए नया हूं)।

यह एक और समस्या हो सकती है जिसे मैंने स्वयं सामना किया है। कुछ फोनों पर किसी जेएसओएन लाइब्रेरी की तरह एंड्रॉइड लाइब्रेरी गायब होने के साथ कुछ समस्या थी।

मैं आपको सलाह देता हूं कि वास्तव में एनपीई प्राप्त करने वाले फ़ोनों पर नज़र डालें - कुछ समानताएं हो सकती हैं।

मेरे मामले में यह एचटीसी डिजायर जेड था, जो जेएसओएन लाइब्रेरी गायब था और इसलिए जेएसओएन भाग को हर बार बंद कर दिया गया था। बाद में एचटीसी द्वारा डिजायर जेड के रोम में हॉटफिक्स के साथ समस्या तय की गई थी।

8

ठीक है, मुझे लगता है कि मुझे इस मुद्दे/भ्रम की जड़ मिल गई है।

प्रोजेवार्ड चीजों में से एक कुछ तरीकों से ऑनलाइन है। इस वजह से, मेरे कन्स्ट्रक्टर के निचले हिस्से में मेरे सेटअप कॉन्टिन्यू() फ़ंक्शन की पूरी सामग्री सीधे मेरे कन्स्ट्रक्टर की सामग्री में जोड़ दी गई थी। तो अब मेरे पास समीक्षा करने के लिए एक गुच्छा अधिक कोड है, और मुझे एनपीई के लिए कुछ और संभावनाएं दिखाई देती हैं। मुझे पूरा यकीन है कि मैं अपने मुद्दे के नीचे पहुंच जाऊंगा।

मैंने यह पता लगाया कि obfuscated.jar जो प्रोजेगार्ड उत्पन्न करता है, और इसे एक डिकंपेलर के माध्यम से चला रहा है। यह एक दिलचस्प अभ्यास है क्योंकि आपको प्रोगार्ड के आंतरिक कार्यों में थोड़ा अधिक अंतर्दृष्टि मिलती है। मैं उन लोगों के लिए अत्यधिक अनुशंसा करता हूं जो उनके कोड पर प्रोजेक्ट के प्रभाव को बेहतर ढंग से समझना चाहते हैं।

+0

संसाधित कोड को देखते हुए बहुत उपयोगी हो सकता है। आपको यह सुनिश्चित करना चाहिए कि आप ProGuard (4.6 या 4.7 बीटा) के नवीनतम संस्करण का उपयोग कर रहे हैं। विशेष रूप से, संस्करण 4.6 में स्थाई प्रारंभिक से संबंधित एक फिक्स शामिल है जो चलने वाले तरीकों (इनलाइन) के कारण नहीं चल रहा है। फिर भी, यह आश्चर्य की बात है कि समस्या लगातार नहीं होती है। –

+0

प्रोगार्ड इन-लाइनिंग कोड के बारे में हिस्सा एक बड़ी मदद थी। अब मुझे एहसास हुआ कि मेरे उपयोगकर्ता ने क्रैश/स्टैक निशान क्यों जमा किए हैं, एनपीई के कारण कोड की वास्तविक रेखा के बजाय एक विधि हस्ताक्षर पर समाप्त होने लगते हैं। यह बहुत बुरा है, यह विशेष रूप से समस्या के कारण रेखा को इंगित नहीं करता है; अगर विधि में कोड का एक टन होता है (जैसे घास के मैदान में सुई ढूंढना) तो यह वास्तव में चूसना होगा। –

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