【问题标题】:Show Interstitial ads on a natural breaking point in game在游戏的自然转折点展示插页式广告
【发布时间】:2014-11-19 17:22:23
【问题描述】:

我无法在游戏的自然断点上显示插页式添加。 现在我可以加载和显示这些插页式添加,即使我正在更改活动。

我的主要问题是我无法决定何时显示这些添加。

我使用 OpenGl ES 并使用 badlogic 框架。因此,每次切换屏幕时都会一遍又一遍地调用 mainactivity。

这是我现在创建的,通过使用我的共享首选项和一个小助手类,我可以追踪添加的阶段。

  public abstract class GLGame extends Activity implements Game, Renderer {
  enum GLGameState {
    ....  
}
   GLSurfaceView glView;    
   GLGraphics glGraphics;
   ....       
  public InterstitialAd interstitial;

  private static final String AD_UNIT_ID = "****";


@Override 
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    glView = new GLSurfaceView(this);
    glView.setRenderer(this);

    setContentView(glView);

    glGraphics = new GLGraphics(glView);

   .... 

// my shared pref is set to 0 when add is not loaded
       if (addcheck.showadd(getApplicationContext())==0){
       interstitial = new InterstitialAd(getApplicationContext());
    interstitial.setAdUnitId(AD_UNIT_ID);

       // Create ad request.
       AdRequest adRequest = new AdRequest.Builder()
       .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
           .addTestDevice("****")
       .build();

    // Begin loading your interstitial.
    // I set my shared pref to 1 to tell the add is loaded, for later use in the game
         interstitial.loadAd(adRequest);
     interstitial.setAdListener(new AdListener(){
          public void onAdLoaded(){
              addcheck.setadd(1,getApplicationContext());
                          }});
    }


 // Somewhere in my game I set the pref to 2, where I want to show the add. 
     if (addcheck.showadd(getApplicationContext())==2&interstitial.isLoaded()){
        displayInterstitial();
 // after showing the add, I put my pref back to 1, so I it wont show later      
        addcheck.setadd(1,getApplicationContext());
            }

}
public void displayInterstitial() {
      if (interstitial.isLoaded()) {
        interstitial.show();
      }
    }

在我的例子中,我将从同一个 mainactivity 中调用 displayInterstitial,但是这个 mainactivity 会重新加载几次。我认为插页式广告不再有效,因为我在 interstitial.isLoaded() 上收到空指针错误

这是一些 logcat 输出,这不是我的主要问题。

07-13 21:49:53.009: E/AndroidRuntime(29230): FATAL EXCEPTION: main
07-13 21:49:53.009: E/AndroidRuntime(29230): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.badlogic.androidgames.glbasics/com.glbasics.MainScreen}: java.lang.NullPointerException
07-13 21:49:53.009: E/AndroidRuntime(29230):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
07-13 21:49:53.009: E/AndroidRuntime(29230):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)

有人知道如何在我想要的时候显示这些加载的添加吗?偏好只是我在玩的一个想法。

【问题讨论】:

  • 我的解决方案有效吗?
  • 我还在努力。我会及时通知你。
  • 好的。如果您不想使用界面,请调用 GLGame.showInterstitialAd()。只需确保静态定义 interstitial 和 showInterstital()
  • 这实际上是我一段时间的工作,但弹出相同的消息。今晚再试一次。
  • 最后一个选项不起作用,因为切换屏幕时会重新加载主屏幕。这个原因: java.lang.IllegalStateException: isLoaded 必须在主 UI 线程上调用。我去试试你说的界面

标签: android admob interstitial


【解决方案1】:

首先,要解决 NPE,必须在广告关闭或加载失败时重建插页式广告。你这样做 onAdClosed() 和 onAdFailed() 回调:

  public abstract class GLGame extends Activity implements Game, Renderer{
  public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       interstitial = new InterstitialAd(GLGame.this);
        interstitial.setAdUnitId("*****");
         reloadInterstitials();
        // Create ad request
        AdRequest adRequest = new AdRequest.Builder().build();

        // Begin loading your interstitial
        interstitial.loadAd(adRequest);
  }

private void reloadInterstitials(){
        interstitial.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {
                // TODO Auto-generated method stub
                super.onAdLoaded();
            }
            @Override
            public void onAdFailedToLoad(int errorCode) {
                // TODO Auto-generated method stub
                super.onAdFailedToLoad(errorCode);
                 interstitial = new InterstitialAd(GLGame.this);
                    interstitial.setAdUnitId("*****");
                    // Begin loading your interstitial
                    interstitial.loadAd(new AdRequest.Builder().build());
                    loadInterCallBacks();
            }

            @Override
            public void onAdOpened() {
                // TODO Auto-generated method stub
                super.onAdOpened();
            }

            @Override
            public void onAdClosed() {
                // TODO Auto-generated method stub
                super.onAdClosed();
                interstitial = new InterstitialAd(GLGame.this);
                interstitial.setAdUnitId("****");
                loadInterCallBacks();
                // Begin loading your interstitial
                interstitial.loadAd(new AdRequest.Builder().build());
            }

            @Override
            public void onAdLeftApplication() {
                // TODO Auto-generated method stub
                super.onAdLeftApplication();
            }
        });

    }

//显示插页的方法

public void displayInterstitial(){
        if(interstitial.isLoaded())
            interstitial.show();
    }

}

要回答主要问题,您可以使用侦听器在需要时显示已加载的广告。

第 1 步:定义接口

public interface MyInterstitialListener {

    public void showInterstitial();
}

第二步:让GLGame实现接口:

public abstract class GLGame extends Activity implements Game, Renderer, MyInterstitialListener{    
public void showInterstitial() {
     runOnUiThread(new Runnable(){
        @Override
        public void run() {
            // TODO Auto-generated method stub
            displayInterstitial();
        } });
}

}

最后在任一 Screen 类中,展示广告:

public class LevelOneScreen extends GLScreen {
MyInterstitialListener mL;

public LevelOnecreen(Game game) {
        super(game);
    mL = (MyInterstitialListener)game;
    mL.showInterstitial();
}
}

您可以在游戏的自然断点上调用 MyInterstitialListener#showInterstitial()。如果您想在游戏循环中调用它,请使用布尔标志调用一次:

public void update(float deltaTime) {  //game loop.
     if(!adCalled){ 
     mL.showInterstitial();
     adCalled = true;
     }
}

【讨论】:

  • 哇,非常感谢!它一次就奏效了。实际上我不明白它到底做了什么,所以我打算研究一下接口。完美!
  • 现在可能是稍后的反应,但我现在有内存泄漏,很难解决。我现在面临的问题是每次启动 GLGame(每个活动都调用此 GLGame)时都会加载一个新广告。因此,在切换活动后,我看到我的内存在增加,并且多个 logcat 输出显示 Ad Finished Loading。我喜欢删除所有旧加载的添加,但由于界面原因,它们似乎都保留在内存中。
  • 删除所有旧加载的广告?如果您的插页式引用是全局变量,则不应该有旧的。不要制作和展示插页式广告,看看是否仍会导致内存泄漏。
  • 界面仍然有点神秘,但我快到了。如果你说它是一个全局变量,那么我只需要加载一次。我现在可以解决这个问题了。我已经调试了一周的内存泄漏。我找到了两个,第一个解决了,第二个肯定是admob。毫无疑问。
  • 已修复,GC 似乎对 admob 进行了一些清理。我不是每次都创建广告,而是每次都调用 displayinterstitial 并希望加载广告。当这不起作用时(因此内存中没有广告),我设置了首选项以便重新加载。它只需要两次活动切换,但这也可以很好地减少广告数量。并且没有泄漏内存。再次感谢娜娜的指导,不胜感激。
【解决方案2】:

请参考以下代码。

private void displayAdmobInterstitialAd(InterstitialAd pAd){
    if(pAd.isLoaded()){
        pAd.show();
    }
}

public void popAdmobInterstitialAd(){
    final InterstitialAd adMobInterstitialAd = new InterstitialAd(ResourcesManager.getInstance().activity);
    adMobInterstitialAd.setAdUnitId("Your AD unit ID");
    final AdRequest adRequest = new AdRequest.Builder().build();
    ResourcesManager.getInstance().getActivity().runOnUiThread(new Runnable() {

        @Override
        public void run() {
            adMobInterstitialAd.loadAd(adRequest);
        }
    });

    adMobInterstitialAd.setAdListener(new AdListener() {
        public void onAdLoaded(){
            displayAdmobInterstitialAd(adMobInterstitialAd);
        }
    });
}

我在我的 andengine 项目的 sceneManager 类上使用了这个方法。 只需在 runOnUiThread 上执行 loadAd...就是这样。

my android app

【讨论】:

    猜你喜欢
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多