【问题标题】:Andengine/OpenGL app freezes after resuming from backgroundAndengine/OpenGL 应用程序从后台恢复后冻结
【发布时间】:2015-09-15 14:09:35
【问题描述】:

我开发了一个 andengine 应用程序,该应用程序运行良好,除非应用程序进入后台。我发现了 2 个问题。

1) 如果我通过按主页按钮离开应用程序,然后再次返回,它只会显示一个空白的黑屏,并且没有任何反应(无交互)。

2) 如果我在应用程序中展示广告并关闭应用程序,应用程序会冻结并且游戏中没有任何操作(触摸、按下按钮等)

我无法弄清楚发生了什么? 这是我的 GameActivity 课程。我不确定问题是否出在此处。

public class GameActivity extends BaseGameActivity {

            public static float CAMERA_WIDTH=0;
            public static float CAMERA_HEIGHT=0;
            private FollowCamera camera;

            SharedPreferences prefs;
            public SharedPreferences.Editor editor;

            public GameHelper mHelper;
            public static Tracker easyTracker;
        public GoogleAnalytics analytics;

            public void setHighScore(int score) {
                SharedPreferences.Editor settingsEditor = prefs.edit();
                settingsEditor.putInt(Constants.KEY_HISCORE, score);
                settingsEditor.apply();
            }

            public int getHighScore() {
                    return prefs.getInt(Constants.KEY_HISCORE, 0);
            }


            @Override
            public Engine onCreateEngine(EngineOptions pEngineOptions)
            {
                    return new LimitedFPSEngine(pEngineOptions, 60);
            }

            @Override
            public boolean onKeyDown(int keyCode, @NonNull KeyEvent event)
            {  
                if (keyCode == KeyEvent.KEYCODE_BACK)
                {
                    SceneManager.getInstance().getCurrentScene().onBackKeyPressed();
                }
                return false;
            }

            @Override
            public EngineOptions onCreateEngineOptions() {
                    ScreenDimentions();
                    prefs = PreferenceManager.getDefaultSharedPreferences(this);
                    camera = new FollowCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
                    EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.camera);
                    engineOption.getAudioOptions().setNeedsMusic(true);
                    engineOption.getAudioOptions().setNeedsSound(true);
                    engineOption.getRenderOptions().getConfigChooserOptions().setRequestedMultiSampling(true);
                    engineOption.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
                    engineOption.getTouchOptions().setNeedsMultiTouch(true);
                    return engineOption;
            }

            public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws IOException {
                    ResourcesManager.prepareManager(mEngine, this, camera, getVertexBufferObjectManager());
                    pOnCreateResourcesCallback.onCreateResourcesFinished();
            }

            @Override
            public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
                            throws IOException {
                    SceneManager.getInstance().createSplashScene(pOnCreateSceneCallback);
            }

            @Override
            public void onPopulateScene(Scene pScene,
                            OnPopulateSceneCallback pOnPopulateSceneCallback)
                            throws IOException {
                    mEngine.registerUpdateHandler(new TimerHandler(2f, new ITimerCallback() {

                            @Override
                            public void onTimePassed(TimerHandler pTimerHandler) {
                                    mEngine.unregisterUpdateHandler(pTimerHandler);
                                    SceneManager.getInstance().createGameScene();
                            }
                    }));
                    pOnPopulateSceneCallback.onPopulateSceneFinished();
            }

            @Override
            public synchronized void onResumeGame() {
                    super.onResumeGame();
            }

            @Override
            public synchronized void onPauseGame() {
                super.onPauseGame();
            }

            public static float Screen_width_inch;
            public static float Screen_height_inch;
            public static float Screen_width_cm;
            public static float Screen_height_cm;
            public static int Screen_width_pixels;
            public static int Screen_height_pixels;
            public static float Screen_dpi;
//            public static float Screen_size_inch;
            public static float density;
            public void ScreenDimentions(){
                final DisplayMetrics dm = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(dm);
                Screen_dpi = dm.scaledDensity;
                density = dm.density;
                Screen_width_pixels = dm.widthPixels;
                Screen_height_pixels = dm.heightPixels;
                CAMERA_WIDTH = Screen_width_pixels;
                CAMERA_HEIGHT = Screen_height_pixels;
                Screen_width_inch = 1.00f*dm.widthPixels/(1.00f*dm.xdpi);
                Screen_height_inch = 1.00f*dm.heightPixels/(1.00f*dm.ydpi);
                Screen_width_cm = Screen_width_inch*2.56f;
                Screen_height_cm = Screen_height_inch*2.56f;
            }
          @Override
          public void onDestroy()
          {
                  super.onDestroy();
          }
          @Override
          public void onResume() {
            super.onResume();
            if(mHelper==null){
              mHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
            }
            if (adView != null) {
                adView.resume();
            }
          }
          @Override
          public void onPause() {
            super.onPause();
            if (adView != null) {
                  adView.pause();
            }
          }
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                analytics = GoogleAnalytics.getInstance(this);
//        analytics.getLogger().setLogLevel(Logger.LogLevel.VERBOSE);
                analytics.setLocalDispatchPeriod(1800);

                easyTracker = analytics.newTracker("ID");
                easyTracker.enableAdvertisingIdCollection(true);
                easyTracker.enableAutoActivityTracking(true);
                easyTracker.enableExceptionReporting(true);

                mHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
//                mHelper.enableDebugLog(true, "GameHelper");
                editor = prefs.edit();
                GameHelperListener listener = new GameHelper.GameHelperListener() {
                    @Override
                    public void onSignInSucceeded() {
                        // handle sign-in succeess
                        Log.d("auth", "sign in successful");
                        editor.putBoolean("firstSignIn", true);
                        editor.apply();
                        if(prefs.getInt("autoSignIn", 0)==1){
                            trackEvent("social", "auth", "first_login");
                        }
                        trackEvent("social", "auth", "googlt_login");
                    }
                    @Override
                    public void onSignInFailed() {
                        // handle sign-in failure (e.g. show Sign In button)
                        Log.d("leaderboard","sign in failed");
                    }

                };
                mHelper.setup(listener);
                mInterstitialAd = new InterstitialAd(this);
                mInterstitialAd.setAdUnitId("ID");
             // Create ad request.
                AdRequest intestitialAdRequest = new AdRequest.Builder().build();
             // Begin loading your interstitial.
                mInterstitialAd.loadAd(intestitialAdRequest);
                mInterstitialAd.setAdListener(new AdListener() {
                    @Override
                    public void onAdLoaded() {
//                        Toast.makeText(MyActivity.this,
//                                "The interstitial is loaded", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onAdClosed() {
                        // Proceed to the next level.
//                        goToNextLevel();
                        AdRequest intestitialAdRequest = new AdRequest.Builder().build();
                        mInterstitialAd.loadAd(intestitialAdRequest);
                    }
                });
            }

            public static void displayInterstitial() {
                if (mInterstitialAd.isLoaded()) {
                    mInterstitialAd.show();
                }
            }
            @Override
            protected void onStart() {
                super.onStart();
                if(prefs.getInt("autoSignIn", 0)==0){
                    mHelper.beginUserInitiatedSignIn();
                    mHelper.onStart(this);
                    editor.putInt("autoSignIn", 1);
                    editor.commit();
                    trackEvent("social", "auth", "autoSignIn_shown");
                }
                if (prefs.getBoolean("firstSignIn", false)) {
////                    // auto sign in
                    if(!mHelper.isSignedIn()){
                        mHelper.getApiClient().connect();
                    }
                }

            }

            @Override
            protected void onStop() {
                super.onStop();
            }

            @Override
            protected void onActivityResult(int request, int response, Intent data) {
                super.onActivityResult(request, response, data);
                mHelper.onActivityResult(request, response, data);
            }

//          Banner ad through google api
            public static AdView adView;
            public static AdRequest adRequest;
            public static FrameLayout frameLayout;
            public static FrameLayout.LayoutParams adViewLayoutParams;
            public static InterstitialAd mInterstitialAd;

            @Override
            protected void onSetContentView() {

                frameLayout = new FrameLayout(this);
                final FrameLayout.LayoutParams frameLayoutLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//                Log.d("Ads","frame layout params are "+frameLayoutLayoutParams.width+" and "+frameLayoutLayoutParams.height);
                adView = new AdView(this);
                new AdView(this);
                adView.setAdSize(AdSize.BANNER);

                adView.setAdUnitId("ID");
//                Log.d("Ads","AdView banner size is "+adView.getWidth()+" and "+adView.getHeight());
                adViewLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL);
//                Log.d("Ads","ad layout params are "+adViewLayoutParams.width+" and "+adViewLayoutParams.height);
                this.mRenderSurfaceView = new RenderSurfaceView(this);
                mRenderSurfaceView.setRenderer(this.mEngine, this);
                    adRequest = new AdRequest.Builder()
                            .addTestDevice("TEST_ID")
                            .addTestDevice("TEST_ID")
                            .build();

                    adView.setAdListener(new AdListener() {
                        @Override
                        public void onAdLoaded() {
                            frameLayout.removeView(adView);  // added to remove addview error
                            //                        frameLayout.addView(mRenderSurfaceView, frameLayoutLayoutParams);
                            frameLayout.addView(adView,adViewLayoutParams);
                            // Save app state before going to the ad overlay.
                        }
                    });
                final FrameLayout.LayoutParams surfaceViewLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
                frameLayout.addView(this.mRenderSurfaceView, surfaceViewLayoutParams);
                this.setContentView(frameLayout, frameLayoutLayoutParams);
                    adView.loadAd(adRequest);
            }

        // Event Tracking
        public void trackEvent(String category,String action,String label){
            try {
                easyTracker.send(new HitBuilders.EventBuilder()
                        .setCategory(category)
                        .setAction(action)
                        .setLabel(label)
                        .build());
            }
            catch (Exception error){

            }
        }
    }

【问题讨论】:

    标签: android opengl-es andengine android-lifecycle


    【解决方案1】:

    问题编号。 1:如果 OpenGL 上下文丢失,就会发生这种情况。您可以强制上下文保持活跃。它仍然可能会丢失,但很少见。您可以处理丢失的事件并重新加载纹理(如果您没有更改某些内容,这实际上应该由引擎自动完成)。您可以在 AndEngine 论坛上找到大量关于如何实现这一目标的文章。

    问题编号。 2:是否调用了引擎的所有resume/pause方法来保证引擎正确的暂停?

    【讨论】:

    • 嗨。我认为这两个问题是相互关联的。虽然我不认为我在 AndEngine 中进行了任何更改,因为我的其他应用程序运行良好,在 onStart/Stop/resume/pause/create 方法上具有几乎相同的代码。您是否知道哪种方法通常会导致这些问题?
    猜你喜欢
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多