简体   繁体   中英

Android fragment layout not loading when showing an Admob interstitial ad in OnCreateView

I've got some problem with displaying ads in my app using AdMob. The problem is as stated in the topic.

This is my starting activity class:

package com.example.admobinterstitial;

import android.os.Bundle;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

import android.support.v4.app.FragmentActivity;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends FragmentActivity
{
    public static InterstitialAd mInterstitialAd;

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        // Super
        super.onCreate(savedInstanceState);
         // Turn off the window's title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);
         // Fullscreen mode
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        mInterstitialAd = new InterstitialAd(this);
        mInterstitialAd.setAdUnitId(getResources().getString(R.string.loading_add_id));

        mInterstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdClosed() {
                requestNewInterstitial();
            }
        });
        requestNewInterstitial();

        if (findViewById(R.id.fragment_container) != null) 
        {
            if (savedInstanceState != null) {
                return;
            }
            // Create a new Fragment to be placed in the activity layout
            Fragments.MenuFragment firstFragment = new Fragments.MenuFragment();

            // In case this activity was started with special instructions from an
            // Intent, pass the Intent's extras to the fragment as arguments
            firstFragment.setArguments(getIntent().getExtras());

            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment, firstFragment.getClass().toString()).commit();
        }  
    }

    private void requestNewInterstitial() {
        AdRequest adRequest = new AdRequest.Builder()
                  .addTestDevice("my test device ID blabla")
                  .build();

        mInterstitialAd.loadAd(adRequest);
    }


}

Main Activity layout:

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <FrameLayout
        android:id="@+id/fragment_container"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_color" >
    </FrameLayout>

</RelativeLayout>

Here are 2 fragments in my app:

package com.example.admobinterstitial;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class Fragments
{
    public static class MenuFragment extends Fragment 
    {
        Context mContext;

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            mContext = activity;
        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            final View rootView = inflater.inflate(R.layout.menu_fragment, container, false);

            Button myButton = (Button) rootView.findViewById(R.id.myButton);
            myButton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                    NextFragment newFragment = new NextFragment();
                    FragmentManager man = ((FragmentActivity)mContext).getSupportFragmentManager();

                    android.support.v4.app.FragmentTransaction transaction = man.beginTransaction();
                    transaction.replace(R.id.fragment_container, newFragment, newFragment.getClass().toString());
                    transaction.addToBackStack(null);
                    transaction.commit();
                }
            });

            return rootView;
        }
    };

    public static class NextFragment extends Fragment 
    {       
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            final View rootView = inflater.inflate(R.layout.next_fragment, container, false);

            //TODO After showing the ad here, views in my R.layout.next_fragment won't show up after closing the ad.
            //With those 2 lines commented, the views show up correctly...
            if (MainActivity.mInterstitialAd.isLoaded()) 
                MainActivity.mInterstitialAd.show();

            return rootView;
        }
    };
}

In MainActivity I just set my R.id.fragment_container to my MenuFragment. In MenuFragment I've got button which starts NextFragment (replaces R.id.fragment_container with this fragment). The problem is in NextFragment class in OnCreateView...

I've already spent a lot of time trying to solve the problem and now I'm so desperate that I even prepared a sample small eclipse project showing the issue: https://drive.google.com/file/d/0ByRNGNhz-adOQ091OU15c3ZUckE/view?usp=sharing

You'll have to change your advertisement unit id in strings.xml and set your test device id in MainActivity.java in requestNewInterstitial method to show the ad... (and probably fix some linking errors? - not sure if google play services will be linked correctly for you guys)

And I'm going to give bounty to whoever sheds some light to resolve the problem...

update 1: On one of my devices - samsung galaxy s4 mini - the problem occurs no matter if I use test ads or real ads. But it seems like on my another device LG-D320n the problem seems to occur only when using test ads... I'm totally confused now...

update 2: adding full logcat of app (there's no any crash in app but lots of messages thrown. After closing the adevertisement there's just no views and I manually exit from the app using "back button")

11-05 13:26:13.018: W/GooglePlayServicesUtil(15088): Google Play services out of date.  Requires 8115000 but found 5084034
11-05 13:26:13.018: W/Ads(15088): Using InterstitialAdManager from the client jar.
11-05 13:26:13.018: I/Ads(15088): Starting ad request.
11-05 13:26:13.068: W/GooglePlayServicesUtil(15088): Google Play services out of date.  Requires 8115000 but found 5084034
11-05 13:26:13.068: E/GooglePlayServicesUtil(15088): GooglePlayServices not available due to error 2
11-05 13:26:13.108: I/ActivityManager(15088): Timeline: Activity_idle id: android.os.BinderProxy@4205cbf0 time:107329054
11-05 13:26:13.188: I/Ads(15088): Not on service, return
11-05 13:26:13.488: I/chromium(15088): [INFO:CONSOLE(0)] "Document was loaded from Application Cache with manifest https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.appcache", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:13.498: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache Checking event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:13.498: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache Checking event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:13.498: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache NoUpdate event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:13.498: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache NoUpdate event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:13.968: D/dalvikvm(15088): GC_FOR_ALLOC freed 1811K, 26% free 9199K/12400K, paused 52ms, total 52ms
11-05 13:26:14.038: W/AwContents(15088): nativeOnDraw failed; clearing to background color.
11-05 13:26:14.148: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:14.218: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:14.458: I/Ads(15088): Ad finished loading.
11-05 13:26:15.778: I/ViewRootImpl(15088): ViewRoot's Touch Event : Touch Down
11-05 13:26:15.898: I/ViewRootImpl(15088): ViewRoot's Touch Event : Touch UP
11-05 13:26:15.958: D/dalvikvm(15088): GC_FOR_ALLOC freed 2271K, 41% free 7316K/12400K, paused 31ms, total 32ms
11-05 13:26:16.308: I/ActivityManager(15088): Timeline: Activity_launch_request id:com.example.admobinterstitial time:107332251
11-05 13:26:16.318: I/Ads(15088): Ad opening.
11-05 13:26:16.378: D/dalvikvm(15088): GC_FOR_ALLOC freed 1553K, 40% free 7450K/12400K, paused 23ms, total 23ms
11-05 13:26:16.418: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:16.488: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:16.738: I/ActivityManager(15088): Timeline: Activity_idle id: android.os.BinderProxy@41f92ef0 time:107332684
11-05 13:26:18.418: I/ViewRootImpl(15088): ViewRoot's Touch Event : Touch Down
11-05 13:26:18.478: I/ViewRootImpl(15088): ViewRoot's Touch Event : Touch UP
11-05 13:26:18.508: I/Ads(15088): Starting ad request.
11-05 13:26:18.578: I/ActivityManager(15088): Timeline: Activity_idle id: android.os.BinderProxy@4205cbf0 time:107334523
11-05 13:26:18.648: I/Ads(15088): Not on service, return
11-05 13:26:18.748: I/chromium(15088): [INFO:CONSOLE(0)] "Document was loaded from Application Cache with manifest https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.appcache", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:18.748: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache Checking event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:18.758: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache Checking event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:18.878: D/dalvikvm(15088): GC_FOR_ALLOC freed 593K, 29% free 8904K/12400K, paused 19ms, total 19ms
11-05 13:26:18.958: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache NoUpdate event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:18.958: I/chromium(15088): [INFO:CONSOLE(0)] "Application Cache NoUpdate event", source: https://googleads.g.doubleclick.net/mads/static/mad/sdk/native/sdk-core-v40.html (0)
11-05 13:26:19.118: W/AwContents(15088): nativeOnDraw failed; clearing to background color.
11-05 13:26:19.248: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:19.308: I/chromium(15088): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
11-05 13:26:19.358: I/Ads(15088): Ad finished loading.
11-05 13:26:21.348: I/ViewRootImpl(15088): ViewRoot's KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=158, metaState=0, flags=0x48, repeatCount=0, eventTime=107337287, downTime=107337287, deviceId=7, source=0x101 } to com.android.internal.policy.impl.PhoneWindow$DecorView{41e7ae60 V.E..... R....... 0,0-480,800}
11-05 13:26:21.458: I/ViewRootImpl(15088): ViewRoot's KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=158, metaState=0, flags=0x48, repeatCount=0, eventTime=107337403, downTime=107337287, deviceId=7, source=0x101 } to com.android.internal.policy.impl.PhoneWindow$DecorView{41e7ae60 V.E..... R....... 0,0-480,800}
11-05 13:26:22.358: I/ViewRootImpl(15088): ViewRoot's KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=158, metaState=0, flags=0x48, repeatCount=0, eventTime=107338296, downTime=107338296, deviceId=7, source=0x101 } to com.android.internal.policy.impl.PhoneWindow$DecorView{41e7ae60 V.E..... R....... 0,0-480,800}
11-05 13:26:22.468: I/ViewRootImpl(15088): ViewRoot's KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=158, metaState=0, flags=0x48, repeatCount=0, eventTime=107338412, downTime=107338296, deviceId=7, source=0x101 } to com.android.internal.policy.impl.PhoneWindow$DecorView{41e7ae60 V.E..... R....... 0,0-480,800}

Try to wrap your ad-showing code in fragment like this:

rootView.post(
        new Runnable() {
            @Override
            public void run() {
                if (MainActivity.mInterstitialAd.isLoaded()) 
                    MainActivity.mInterstitialAd.show();
            }
        }
);

It is possible that intersitial ad somehow harms your fragment's lifecycle.

Or you can try to experiment with postDelayed(Runnable runnable, long delay); and show the ad with some properly-set delay. Maybe that would help.

Are You using Emulator to run your code or Device ?

switch (isGooglePlayServicesAvailable(this)) {  
  case 2: //out date  
        try {  
            GooglePlayServicesUtil.getErrorDialog(2, this, 0).show();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        break;  
}

This will prompt an update dialog for the user to update play services.

I think you are running your app with lower Version of Play service Library. update it and then run your code.

Refer https://groups.google.com/forum/#!topic/google-admob-ads-sdk/A_NpbD6leg0

You are hosing yourself by storing the interstitial as a static on MainActivity. Never do that.

You should instead be passing a message from your Fragment to its containing Activity and it should be responsible for displaying the ad.

Otherwise you are almost certainly going to start leaking memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM