屏幕关闭时,Android onResume会调用

时间:2015-03-09 11:44:49

标签: android android-activity onresume android-anr-dialog

首先,我不会说英语,所以请原谅我的可怕语法。

我尝试使用GLSurfaceView创建Android游戏。 我用日语阅读"Beginning of Android Game"链接是示例代码)并模仿其代码,因此我的游戏几乎正常。 但我有一个问题。 当android关闭屏幕时,onPause将按预期调用活动。 但有时(并非总是)调用onResume,然后再次调用onPause(),尽管屏幕仍为黑色。 在onResume我致电GLSurfaceView()。resume,因此也会调用onSurfaceCreated()onSurfaceChanged()。 在此之后,游戏推出了ANR。

[预期流程]
onPause - (打开屏幕) - onResume - onSurfaceCreated - onSurfaceChanged
[有问题的流程]
onPause - onResume - onPause - onSurfaceCreated - onSurfaceChanged - (打开屏幕) - ANR

即使在有问题的情况下,也会正常调用GLSurfaceView.onDrawFrame,并且正在渲染游戏。 但它不接受任何敲击。是否存在无限循环?

我发现了类似的问题herehere。 但我认为没有配置改变。 在Android Manifest中,

android:configChanges="keyboard|keyboardHidden|orientation|screenSize

已经宣布。 我无法将我的代码移到Application类中,因为我想在onSurfaceCreated方法中做一些事情(例如重新加载一些纹理)。

所以我的问题是......

  

为什么调用onResume方法?

     

为什么会导致ANR?
  我怎样才能避免这种ANR?
  编辑:问题解决了。我很感激!

这是我的活动。

public abstract class GLGame extends Activity implements Game, Renderer {
    enum GLGameState {
        Initialized,
        Running,
        Paused,
        Finished,
        Idle
    }
    /////////////////////////////inter-ad
    private static class AdHandler extends Handler {
        private final WeakReference<GLGame> mActivity;
        AdHandler(GLGame activity) {
            mActivity = new WeakReference<GLGame>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            GLGame activity = mActivity.get();
            switch(msg.what){
            case 0:
                if (activity != null) {
                    activity.showInterstitial();
                }
                break;
            case 1:
                if (activity != null) {
                    activity.prepareInterstitial();
                }
                break;
            }

            return;
        }
    };
    Handler handler =new AdHandler(this);
    /////////////////////////////inter-ad    

    //ad
    static InterstitialAd interstitial;
    static AdRequest adRequest;
    AdView adView;
    //////////////////////////////// //ad

    GLSurfaceView glView;
    GLGraphics glGraphics;
    Audio audio;
    Input input;
    FileIO fileIO;
    Screen screen;
    GLGameState state = GLGameState.Initialized;
    Object stateChanged = new Object();
    long startTime = System.nanoTime();

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

        /////////////////////////////calculate and normalize the view size    
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

        float density = displaymetrics.densityDpi/160f;
        int adpix = (int)( 50*density);
        int navvarpix = (int)( 25*density);
        int heightSubAd = displaymetrics.heightPixels -navvarpix-adpix;

        int ratioWidth=10;
        int ratioHeight=16;
        boolean isWidthLong = displaymetrics.widthPixels/(float)heightSubAd > ratioWidth/(float)ratioHeight;
        int width = isWidthLong ? heightSubAd * ratioWidth / ratioHeight : displaymetrics.widthPixels;
        int height = isWidthLong ? heightSubAd : displaymetrics.widthPixels * ratioHeight/ratioWidth;

        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width, height);
        lp.setMargins((displaymetrics.widthPixels-width)/2, 0, 0, (displaymetrics.widthPixels-width)/2);
        ///////////////////////////// //calc    

        glView = new GLSurfaceView(this);
        glView.setLayoutParams(lp);
        glView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
        glView.setRenderer(this);

        adView = new AdView(this, AdSize.BANNER, "MY_NUMBER");
        lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, adpix);
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
        adView.setLayoutParams(lp);

        RelativeLayout layout = new RelativeLayout(this);
        layout.setBackgroundColor(Color.BLACK);
        layout.setId(0);
        layout.addView(glView);
        layout.addView(adView);
        adView.loadAd(new AdRequest());

        setContentView(layout);

        /////////////////////////////////request inter-ad
        interstitial = new InterstitialAd(this, "MY_NUMBER");
        adRequest = new AdRequest();
        adRequest.addTestDevice("MY_NUMBER");
        adRequest.addTestDevice("MY_NUMBER");
        interstitial.loadAd(adRequest);
        /////////////////////////////////inter-ad

        glGraphics = new GLGraphics(glView);
        fileIO = new AndroidFileIO(getAssets());
        audio = new AndroidAudio(this);
        input = new AndroidInput(this, glView, 1, 1);
    }

    public void onResume() {
        super.onResume();
        glView.onResume();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        glGraphics.setGL(gl);

        synchronized(stateChanged) {
            if(state == GLGameState.Initialized)
                screen = getStartScreen();
            state = GLGameState.Running;
            screen.resume();
            startTime = System.nanoTime();
        }
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLGameState state = null;

        synchronized(stateChanged) {
            state = this.state;
        }

        if(state == GLGameState.Running) {
            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;
            startTime = System.nanoTime();

            screen.update(deltaTime);
            screen.present(deltaTime);
        }

        if(state == GLGameState.Paused) {
            screen.pause();
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }

        if(state == GLGameState.Finished) {
            screen.pause();
            screen.dispose();
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }
    }

    @Override
    public void onPause() {
        synchronized(stateChanged) {
            if(isFinishing())
                state = GLGameState.Finished;
            else
                state = GLGameState.Paused;
            while(true) {
                try {
                    stateChanged.wait();
                    break;
                } catch(InterruptedException e) {
                }
            }
        }
        glView.onPause();
        super.onPause();
    }

    public GLGraphics getGLGraphics() {
        return glGraphics;
    }

    @Override
    public Input getInput() {
        return input;
    }

    @Override
    public FileIO getFileIO() {
        return fileIO;
    }

    @Override
    public Graphics getGraphics() {
        throw new IllegalStateException("We are using OpenGL!");
    }

    @Override
    public Audio getAudio() {
        return audio;
    }

    @Override
    public void setScreen(Screen screen) {
        if (screen == null)
            throw new IllegalArgumentException("Screen must not be null");

        this.screen.pause();
        this.screen.dispose();
        screen.resume();
        screen.update(0);
        this.screen = screen;
    }

    @Override
    public Screen getCurrentScreen() {
        return screen;
    }

    @Override
    public Handler getHandler(){
        return handler;
    }

    private void showInterstitial(){
        if(interstitial.isReady()){
            interstitial.show();
        }
    }

    private void prepareInterstitial(){
        interstitial.loadAd(adRequest);
    }

}
谢谢你的善意!

0 个答案:

没有答案