使用libGDX时出现了Looper错误

3
我对Android的活动和其工作原理不是很熟悉,希望您能提供一些相关指导。我在将广告SDK与我的游戏集成时遇到了问题。以下是几个类,以便更好地理解我的代码。基本上,我正在尝试找到一种良好的方式将StartApp SDK(一种广告SDK)与我的libGDX游戏集成。当调用startAppAd.show()和startAppAd.load()时,似乎出现了一个looper错误。
以下是堆栈跟踪(提到了ui线程,并在不同的线程上加载广告):
01-05 15:55:27.646: W/webview_proxy(14876): java.lang.Throwable: Warning: A WebView method was called on thread 'GLThread 8584'. All WebView methods must be called on the UI thread. Future versions of WebView may not support use on other threads.
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.checkThread(WebView.java:1895)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.ensureProviderCreated(WebView.java:1878)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.setOverScrollMode(WebView.java:1935)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.view.View.<init>(View.java:3316)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.view.View.<init>(View.java:3383)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.view.ViewGroup.<init>(ViewGroup.java:432)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.widget.AbsoluteLayout.<init>(AbsoluteLayout.java:52)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:505)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:482)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:468)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:457)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:447)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.Ad.load(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.HtmlAd.load(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAds(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.load(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.onResume(Unknown Source)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.audiack.freetappgame.MainActivity.resume(MainActivity.java:41)
01-05 15:55:27.646: W/webview_proxy(14876):     at Screens.GameScreen.resume(GameScreen.java:699)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.badlogic.gdx.Game.resume(Game.java:41)
01-05 15:55:27.646: W/webview_proxy(14876):     at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:480)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
01-05 15:55:27.646: W/webview_proxy(14876):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
01-05 15:55:27.656: W/IInputConnectionWrapper(14876): getSelectedText on inactive InputConnection
01-05 15:55:27.656: D/SensorManager(14876): onAccuracyChanged :: accuracy = 3
01-05 15:55:27.656: W/IInputConnectionWrapper(14876): setComposingText on inactive InputConnection
01-05 15:55:27.676: W/webview_proxy(14876): java.lang.Throwable: Warning: A WebView method was called on thread 'GLThread 8584'. All WebView methods must be called on the UI thread. Future versions of WebView may not support use on other threads.
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.checkThread(WebView.java:1895)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.getFactory(WebView.java:1889)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.ensureProviderCreated(WebView.java:1882)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.setOverScrollMode(WebView.java:1935)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.view.View.<init>(View.java:3316)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.view.View.<init>(View.java:3383)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.view.ViewGroup.<init>(ViewGroup.java:432)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.widget.AbsoluteLayout.<init>(AbsoluteLayout.java:52)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:505)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:482)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:468)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:457)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.webkit.WebView.<init>(WebView.java:447)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.Ad.load(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.HtmlAd.load(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAds(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.load(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.startapp.android.publish.StartAppAd.onResume(Unknown Source)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.audiack.freetappgame.MainActivity.resume(MainActivity.java:41)
01-05 15:55:27.676: W/webview_proxy(14876):     at Screens.GameScreen.resume(GameScreen.java:699)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.badlogic.gdx.Game.resume(Game.java:41)
01-05 15:55:27.676: W/webview_proxy(14876):     at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:480)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
01-05 15:55:27.676: W/webview_proxy(14876):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
01-05 15:55:27.706: W/dalvikvm(14876): threadid=11: thread exiting with uncaught exception (group=0x4159a438)
01-05 15:55:27.716: E/AndroidRuntime(14876): FATAL EXCEPTION: GLThread 8584
01-05 15:55:27.716: E/AndroidRuntime(14876): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.os.Handler.<init>(Handler.java:121)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebViewClassic$PrivateHandler.<init>(WebViewClassic.java:10636)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebViewClassic.<init>(WebViewClassic.java:1258)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebViewClassic$Factory.createWebView(WebViewClassic.java:2031)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.ensureProviderCreated(WebView.java:1882)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.setOverScrollMode(WebView.java:1935)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.view.View.<init>(View.java:3316)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.view.View.<init>(View.java:3383)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.view.ViewGroup.<init>(ViewGroup.java:432)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.widget.AbsoluteLayout.<init>(AbsoluteLayout.java:52)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.<init>(WebView.java:505)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.<init>(WebView.java:482)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.<init>(WebView.java:468)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.<init>(WebView.java:457)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.webkit.WebView.<init>(WebView.java:447)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.Ad.load(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.HtmlAd.load(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.StartAppAd.loadAds(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.StartAppAd.load(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.StartAppAd.loadAd(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.startapp.android.publish.StartAppAd.onResume(Unknown Source)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.audiack.freetappgame.MainActivity.resume(MainActivity.java:41)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at Screens.GameScreen.resume(GameScreen.java:699)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.badlogic.gdx.Game.resume(Game.java:41)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:480)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
01-05 15:55:27.716: E/AndroidRuntime(14876):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
01-05 15:57:29.236: E/System(14876): Uncaught exception thrown by finalizer
01-05 15:57:29.246: E/System(14876): java.lang.NullPointerException
01-05 15:57:29.246: E/System(14876):    at android.webkit.WebViewClassic.destroy(WebViewClassic.java:2954)
01-05 15:57:29.246: E/System(14876):    at android.webkit.WebViewClassic.finalize(WebViewClassic.java:5366)
01-05 15:57:29.246: E/System(14876):    at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:186)
01-05 15:57:29.246: E/System(14876):    at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:169)
01-05 15:57:29.246: E/System(14876):    at java.lang.Thread.run(Thread.java:856)

看起来似乎与在启动活动中尝试加载广告有关。这是我的启动活动(由于libGDX只在android上运行一个活动):

package com.audiack.freetappgame;

import Screens.FreeTappGame;
import UtilityClasses.StartAppResolver;
import android.os.Bundle;
import android.os.Looper;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.graphics.Texture;
import com.searchboxsdk.android.StartAppSearch;
import com.startapp.android.publish.StartAppAd;

public class MainActivity extends AndroidApplication implements StartAppResolver{
    public StartAppAd startAppAd = new StartAppAd(this);
    public StartAppSearch startAppSearch= new StartAppSearch();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

        StartAppAd.init(this, "101164873", "201640058");
        StartAppSearch.init(this, "101164873", "201640058");

        Texture.setEnforcePotImages(false);
        cfg.useGL20 = true;

        initialize(new FreeTappGame(this), cfg);
        StartAppSearch.showSearchBox(this);
    }
    @Override
    public boolean showAds() {
        startAppAd.load();
        startAppAd.show();
        return true;
    }

    @Override
    public boolean resume() {
        startAppAd.onResume();
        return true;
    }
    @Override
    public boolean backButton() {

        return true;
    }
    @Override
    public boolean pause() {
        startAppAd.onPause();
        return true;
    }
}

你可能已经注意到,我已经实现了一个我创建的接口,并将活动本身传递给ApplicationListener,使libGDX方法能够与活动进行交互。 这是那个接口;根据我数小时的研究,这是在libGDX中集成广告的最佳方法(但这些方法是针对类似的广告SDK而非直接使用StartApp的):

package UtilityClasses;

public interface StartAppResolver {
    public boolean showAds();
    public boolean resume();
    public boolean backButton();
    public boolean pause();
}

最后是ApplicationListener(FreeTappGame类):

package Screens;


import UtilityClasses.Assets;
import UtilityClasses.StartAppResolver;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;

public class FreeTappGame extends Game implements ApplicationListener {
    static float Width;
    static float Height;

    public StartAppResolver startAppResolver;

    public SplashScreen splash_screen;
    public MenuScreen menu_screen;
    public GameScreen game_screen;
    public HighscoreScreen highscore_screen;
    public AboutScreen about_screen;

    public FreeTappGame(StartAppResolver startAppResolver) {
        this.startAppResolver = startAppResolver;
    }

    @Override
    public void create() {
        Width = Gdx.graphics.getWidth();
        Height = Gdx.graphics.getHeight(); 
        Assets.load();

        splash_screen = new SplashScreen(this);
        menu_screen = new MenuScreen(this);
        game_screen = new GameScreen(this);
        highscore_screen = new HighscoreScreen(this);
        about_screen = new AboutScreen(this);

        setScreen(splash_screen);
    }
}

非常感谢您的时间。

1
我想通了,我会尽快发布解决方案。 - Austin Gibb
2个回答

2
我会删除这个帖子,因为这里有一个类似的问题:WebView在Android中未被调用,但是在stackoverflow上并没有太多startapp的解决方案,我认为这个问题对那些试图集成startapp的人们会有益。
@Override
    public boolean showAds() {
        startAppAd.load();
        startAppAd.show();
        return true;
    }

使用

@Override
public boolean showAds() {
    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
        startAppAd.show();

        }
    });
    return true;
}

我把"initialize method"之后放置了"startAppAd.load()":
initialize(new FreeTappGame(this), cfg);
startAppAd.load();

这对我起了作用;我希望这能帮助到其他人。


0

你需要调用

Looper.prepare();

确保在一个线程中只调用一次。这对我很有效:

boolean looperprepare = false;


public void yourmethod(){
    if (!looperprepare) {
        Looper.prepare();
        looperprepare = true;
    }
    ....
}

当我这样做时,它会说我只能创建一个looper。不过我找到了一个可行的解决方案。等我被允许后,我会发布它。 - Austin Gibb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接