2012-03-04 12 views
25

हमारा ऐप मेमोरी रिसाव से काफी कठिन हो रहा है। मैंने पाया है कि रूट कारण पुराने गतिविधियों के संदर्भ में AdMob AdView है। समस्या Android AdMob causes memory leak? प्रश्न और टिप्पणियों/उत्तरों में sublinks में अच्छी तरह से प्रलेखित है। मैंने देखा है कि आईसीएस में समस्या स्पष्ट नहीं है क्योंकि जीसी अंततः गतिविधियों के संदर्भ के साथ वेब व्यू को साफ़ करता है। हालांकि, मेरे एचटीसी ईवीओ 3 डी चलने वाले स्टॉक जिंजरब्रेड कभी भी गतिविधियों को एकत्र नहीं करते हैं और ओओएम त्रुटियों के कारण बल की संख्या को बंद करने पर विचार करते हैं, समस्या हमारे ऐप के लिए बहुत व्यापक है।एडमोब मेमोरी लीक - खाली गतिविधि का उपयोग करके टालना

मैं TacB0sS, https://stackoverflow.com/a/8364820/684893 द्वारा प्रदान किए गए समाधान का पालन करना चाहता हूं। उन्होंने एक खाली गतिविधि बनाने और प्रत्येक AdMob AdView के लिए उसी गतिविधि का उपयोग करने का सुझाव दिया है। रिसाव निहित होगा क्योंकि AdView केवल एक खाली गतिविधि को जीवित रखेगा। उन्होंने गतिविधि के लिए कोड प्रदान किया और इसका संदर्भ कैसे दिया, लेकिन मुझे इस बात का नुकसान हुआ कि वास्तव में इसे हमारे ऐप में कैसे एकीकृत किया जाए। जहां तक ​​मैं कह सकता हूं उसका कोड कभी भी AdMob SDK से कुछ भी नहीं कहता है।

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

अद्यतन 3/6:

जवाब के लिए धन्यवाद एडम (TacB0sS)! विज्ञापन में विज्ञापन बनाने के लिए मुझे स्विच करने में कोई समस्या नहीं है लेकिन विज्ञापन बनाते समय भी मुझे आपकी डमी गतिविधि का उपयोग करने में कठिनाई हो रही है। मेरा कोड वर्तमान में है:

AdMobActivity adActivity = new AdMobActivity(); 
adActivity.startAdMobActivity(this); 

// Create an ad with the activity reference pointing to dummy activity 
AdView adView = new AdView(adActivity.AdMobMemoryLeakWorkAroundActivity, AdSize.IAB_BANNER, "myAdUnitID"); 

// Create an ad request. 
AdRequest adRequest = new AdRequest(); 

// add the ad to the layout and request it to be filled 
RelativeLayout root_main = (RelativeLayout) findViewById(R.id.root_main); 
root_main.addView(adView); 
adView.loadAd(adRequest); 

मैंने इस कोड को मेरी प्रारंभिक गतिविधि के ऑनरेट विधि में रखा है। मुझे उस लाइन पर एक बल मिलता है जहां मैं विज्ञापन दृश्य बनाता हूं, "AdView adView = new AdView (...)"। स्टैकट्रेस स्निपेट:

03-06 00:34:28.098 E/AndroidRuntime(16602): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.udroid.wordgame/org.udroid.wordgame.MainMenu}: java.lang.NullPointerException 
03-06 00:34:28.098 E/AndroidRuntime(16602):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1830) 
(...) 
03-06 00:34:28.098 E/AndroidRuntime(16602): Caused by: java.lang.NullPointerException 
03-06 00:34:28.098 E/AndroidRuntime(16602):  at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:100) 
03-06 00:34:28.098 E/AndroidRuntime(16602):  at com.google.ads.AdView.<init>(SourceFile:78) 
03-06 00:34:28.098 E/AndroidRuntime(16602):  at org.udroid.wordgame.MainMenu.onCreate**(MainMenu.java:71)** <- Line that creates the new AdView 

अपने AdMobActivity प्रारंभ और इसे संदर्भ adview बनाते समय के लिए उचित तरीका क्या है? एक बार फिर धन्यवाद!

अद्यतन 2 3/6:

मैं अपने समस्याओं गतिविधि बनाने पता लगा। मेरा समाधान पूरी तरह कार्यान्वित है और सबसे अच्छा हिस्सा यह है कि वास्तव में मेरी मेमोरी लीक हल करता है। इस समस्या पर दो सप्ताह बिताने के बाद, मैं बहुत खुश हूं कि यह हल हो गया है। यहां पूरे चरण समझाए मैं प्रयोग किया जाता हैं:

एक नई गतिविधि बनाएं बुलाया AdMobActivity:

public final class AdMobActivity extends Activity { 

    public static AdMobActivity AdMobMemoryLeakWorkAroundActivity; 

    public AdMobActivity() { 
     super(); 
     if (AdMobMemoryLeakWorkAroundActivity != null) { 
      throw new IllegalStateException("This activity should be created only once during the entire application life"); 
     } 
     AdMobMemoryLeakWorkAroundActivity = this; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i("CHAT", "in onCreate - AdMobActivity"); 
     finish(); 
    } 

    public static final void startAdMobActivity(Activity activity) { 
     Log.i("CHAT", "in startAdMobActivity"); 
     Intent i = new Intent(); 
     i.setComponent(new ComponentName(activity.getApplicationContext(), AdMobActivity.class)); 
     activity.startActivity(i); 
    } 
} 

अपने AndroidManifest.xml

<activity android:name="org.udroid.wordgame.AdMobActivity" 
    android:launchMode="singleInstance" /> 

के लिए निम्न जोड़ें आप प्रयास करने से पहले डमी AdMobActivity प्रारंभ करने की आवश्यकता किसी भी विज्ञापन को लोड करने के लिए। इस गतिविधि में कुछ भी शामिल नहीं होगा। इसे एक स्प्लिट सेकेंड के लिए प्रदर्शित किया जाएगा और उसके बाद उस गतिविधि को वापस लौटाया जाएगा जिसे आपने इसे बुलाया था। आप इसे उसी गतिविधि में नहीं बना सकते जिसे आप विज्ञापन लोड करना चाहते हैं क्योंकि इसे उपयोग करने से पहले समय में पूरी तरह से प्रारंभ किया जाना चाहिए।मैं एक छप लोड स्क्रीन गतिविधि के onCreate में यह प्रारंभ मुख्य गतिविधि है कि कोई विज्ञापन शुरू होता है होता है से पहले:

// Start the dummy admob activity. Don't try to start it twice or an exception will be thrown 
if (AdMobActivity.AdMobMemoryLeakWorkAroundActivity == null) { 
    Log.i("CHAT", "starting the AdMobActivity"); 
    AdMobActivity.startAdMobActivity(this); 
} 

अब आप कोड में विज्ञापन बनाने के लिए तैयार हैं। अपने एक्सएमएल गतिविधि लेआउट में निम्न LinearLayout जोड़ें। इस लेआउट के आसपास आवश्यक सभी अन्य विचारों को संरेखित करें। कोड में बनाए गए विज्ञापन दृश्य को इस दृश्य के अंदर रखा जाएगा।

<LinearLayout 
android:id="@+id/adviewLayout" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true" 
android:layout_centerHorizontal="true" /> 

गतिविधि यदि आप किसी विज्ञापन लोड adview के लिए एक वैश्विक चर बनाने के लिए चाहते हैं:

AdView adView; 

हमारे एप्लिकेशन में, हम विभिन्न लेआउट जब फोन घूमता लोड। इससे पहले, मैं प्रत्येक घुमाव पर निम्नलिखित कोड बुलाता हूं। यदि आवश्यक हो तो यह विज्ञापन दृश्य बनाता है और इसे विज्ञापनदृश्य में जोड़ता है।

// DYNAMICALLY CREATE AD START 
    LinearLayout adviewLayout = (LinearLayout) findViewById(R.id.adviewLayout); 
    // Create an ad. 
    if (adView == null) { 
     adView = new AdView(AdMobActivity.AdMobMemoryLeakWorkAroundActivity, AdSize.BANNER, "<ADUNITID>"); 
     // Create an ad request. 
     AdRequest adRequest = new AdRequest(); 
     // Start loading the ad in the background. 
     adView.loadAd(adRequest); 
     // Add the AdView to the view hierarchy. The view will have no size until the ad is loaded. 
     adviewLayout.addView(adView); 
    } 
    else { 
     ((LinearLayout) adView.getParent()).removeAllViews(); 
     adviewLayout.addView(adView); 
     // Reload Ad if necessary. Loaded ads are lost when the activity is paused. 
     if (!adView.isReady() || !adView.isRefreshing()) { 
      AdRequest adRequest = new AdRequest(); 
      // Start loading the ad in the background. 
      adView.loadAd(adRequest); 
     } 
    } 
    // DYNAMICALLY CREATE AD END 

अन्त में, OnDestroy विधि सुनिश्चित करें कि आप गतिविधियों में adView.destroy() फोन कर():

@Override 
protected void onDestroy() { 
    adView.destroy(); 
super.onDestroy(); 
} 

किसी को भी किसी और है कि इस पढ़ता है, कृपया, याद रखें कि यह एडम समाधान (TacB0sS) है मेरा नहीं है। मैं सिर्फ दूसरों को लागू करने के लिए आसान बनाने के लिए पूर्ण कार्यान्वयन विवरण प्रदान करना चाहता था। यह AdMob बग प्री-हनीकॉम चलाने वाले ऐप्स के लिए एक बड़ी समस्या है और एडम का समाधान सबसे अच्छा चीज है जिसे मैं इसे रोकने के लिए पा सकता हूं। और यह काम करता है!

+0

वर्क्स एक आकर्षण की तरह लीक !! @ravishi और @ TacB0sS दोनों के लिए धन्यवाद !! – Regis

+0

हाय ravishi ... मुझे इस समाधान के साथ परेशानी हो रही है। क्या आप मेरी मदद कर सकते हैं। यह मेरा सवाल है http://stackoverflow.com/questions/15583994/activity-does-not-launch-from-the-recent-activities-android –

+0

क्या पूर्ण कोड @ravishi से लिंक है? –

उत्तर

17

Ravishi,

आपका प्रश्न बात करने के लिए है, और मैं अपने समाधान में यह पता करने के लिए विफल रहे हैं। जहां तक ​​मैं समाधान बता सकता हूं, मैंने केवल गतिशील रूप से काम किया है, जहां आप एसडीके को कॉल करते समय अपनी गतिविधि चुन सकते हैं ...

मेरे कोड का उपयोग उदाहरण नहीं है, क्योंकि मेरा समाधान एक है मैंने जो कुछ प्रस्तुत किया है, उसके बाद मैंने एक संपूर्ण रैपिंग फ्रेमवर्क शामिल किया है जिसमें मैंने एंड्रॉइड फ्रेमवर्क के चारों ओर निर्माण किया है, जहां एप्लिकेशन के लिए एडमोब संबंध मध्यवर्ती मॉड्यूल के माध्यम से होता है, जो विज्ञापन को गतिशील रूप से एकल गतिविधि उदाहरण का उपयोग करता है।

मुझे सच में संदेह है कि आप एंड्रॉइड एक्सएमएल का उपयोग कर मेमोरी रिसाव से बच सकते हैं।

किसी भी मामले में, यदि आप स्मृति रिसाव कारोबार में कर रहे हैं, आप अपने AsyncTask उपयोग की जाँच हो सकता है ... यह भी अपने स्वयं के स्मृति रिसाव व्यवहार है ... इसलिए यहाँ मेरी solution

सबसे अच्छा है बेस्ट ऑफ लक ...

- अद्यतन - 07/10/14

किसी ने मेरा उत्तर upvoted है अपने propustorase कि यह समस्या अभी भी मौजूद है, यह मेरी मूल जवाब के बाद से लगभग तीन साल, और लोगों को कर दिया गया है अभी भी AdMob की वजह से अपने ऐप्स में मेमोरी लीक है ... Google से ... ने एंड्रॉइड बनाया ....

वैसे भी, मैं बस यह जोड़ना चाहता था कि आपको शायद AdMobActivity का विषय पारदर्शी रूप से सेट करना चाहिए, यह झटके को रोक देगा।

- अद्यतन - 28/02/16

चार साल ...

- अद्यतन - 09/03/17

पांच साल ... गूगल पर किसी ने जगा, और वास्तविक बंदर किराया काम :)

एडम करने के लिए कृपया।

+0

धन्यवाद एडम! अधिक संपादित प्रश्न के लिए कृपया मेरी संपादित पोस्ट देखें। AsyncTask समस्या को इंगित करने के लिए भी धन्यवाद। मैंने शुक्रिया में अभी तक भाग नहीं लिया है या यदि मेरे पास है, तो यह AdMob की तरह एक बड़ी रिसाव नहीं है। – ravishi

+0

आप किस AdMob संस्करण का उपयोग करते हैं? क्या आपने सुपर के पहले या बाद में इसे कॉल किया था। (क्रिएट (...)? आप किस गतिविधि में AdView, डमी गतिविधि, या वास्तविक UI गतिविधि को तुरंत चालू करते हैं। – TacB0sS

+1

मुझे यह काम मिल गया। विवरण के लिए मूल प्रश्न में संपादन देखें। बहुत बहुत धन्यवाद! – ravishi

1

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

6

मैं "play-services-ads: 7.5.0" का उपयोग कर रहा हूं और यह AdMobActivity बनाने के लिए necesary नहीं था। यह काम किया करते थे:

  • adview बनाना dinamically

    mAdView = नए adview (getApplicationContext(), AdSize.BANNER, banner_ad_unit_id); mAdsContainer.addView (mAdView);

  • नष्ट पर LinearLayout से सभी दृश्य निकाल रहा है और नष्ट करने adview

      mAdView.setAdListener(null); 
          mAdsContainer.removeAllViews(); 
          mAdView.destroy(); 
    

Unfortunatelly बीच में आने वाले अभी भी

+1

बहुत बहुत धन्यवाद आदमी। मेरे पास 'लीक कैनरी' लीक संदर्भ 'मुख्य गतिविधि -> संदर्भ ht.a -> static hk.o' था।इससे मुझे इसे हल करने में मदद मिली, जो कि मेरे 'ग्रिडलेआउट प्रबंधक' पर 'NativeExpressAdView' रिसाव था। मैं अपने 'ग्रिडलेआउट प्रबंधक' से सभी विचारों को हटा नहीं रहा था या अपना 'setAdListener' को शून्य में सेट नहीं कर रहा था। Google ने इसे अपने 'NativeExpressAdView' ट्यूटोरियल में पूरी तरह याद किया। –

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