简体   繁体   中英

Andengine/OpenGL app freezes after resuming from background

I have developed an andengine app which works fine except whenever the app goes goes into background. There are 2 issues I am seeing.

1) If i leave the app by pressing the home button and then come back again it just shows me a blank black screen and nothing happens on that(No interaction).

2) If I show an ad in the app and dismiss the app the app freezes and no action works in the game (touch, button press etc)

I am not able to figure out what is happening? Here is my GameActivity class. I am not sure whether the issue lies here.

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){

            }
        }
    }

Problem nr. 1: This happens if the OpenGL Context was lost. You can force the context to stay alive. It can still get lost, but more rarely. You can handle the lost event and reload the textures (which should actually be done by the engine automatically if you haven't changed something). You can find a bunch of articles on how to accomplish that on the AndEngine forum.

Problem nr. 2: Do you call all the resume/pause methods of the engine to ensure that the engine pauses properly?

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