2015-03-08 2 views
0

У меня возникли проблемы с попыткой выяснить, почему моя игра LibGDX работает только один раз на Android.Приложение для Android LibGDX работает только один раз

Предполагая, что игра не установлена ​​на устройстве, когда я запускаю приложение из затмения, игра работает нормально. После закрытия игры и пытаться запустить игру снова, открыв игру на свой телефон (не через затмения), кажется, просто повесить на этом экране навсегда:

http://i.stack.imgur.com/QcLCW.png

Из моего тестирования, я обнаружил, что ни один из моих кодов запуска Android не выполнен, .onCreate() никогда не вызывается. LogCat показывает, что никаких ошибок не возникает, и приложение, похоже, загружает библиотеку LibGDX, а затем ничего. Это вся продукция LogCat: http://i.imgur.com/5DQ5sHY.png Единственное, что поднимает бровь для меня в LogCat является:

Launch timeout has expired, giving up wake lock! 
Activity idle timeout for ActivityRecord 

Иногда очистить кэш и данные для игры на устройстве, кажется, временно исправить проблема, но не всегда.

Это класс AndroidLauncher:

package com.ifs_studios.cheekychameleon.android; 

import java.util.HashMap; 

import android.content.Intent; 
import android.content.IntentSender.SendIntentException; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.RelativeLayout; 
import android.widget.RelativeLayout.LayoutParams; 
import android.widget.Toast; 

import com.badlogic.gdx.backends.android.AndroidApplication; 
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; 
import com.google.android.gms.ads.AdListener; 
import com.google.android.gms.ads.AdRequest; 
import com.google.android.gms.ads.AdSize; 
import com.google.android.gms.ads.AdView; 
import com.google.android.gms.ads.InterstitialAd; 
import com.google.android.gms.analytics.GoogleAnalytics; 
import com.google.android.gms.analytics.HitBuilders; 
import com.google.android.gms.analytics.Logger.LogLevel; 
import com.google.android.gms.analytics.Tracker; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.games.Games; 
import com.google.android.gms.plus.Plus; 
import com.ifs_studios.cheekychameleon.ActionResolver; 
import com.ifs_studios.cheekychameleon.CheekyChameleon; 

/** 
* MemoryBlox Android Launcher. 
* 
* @author BleedObsidian (Jesse Prescott) 
*/ 
public class AndroidLauncher extends AndroidApplication implements ActionResolver, ConnectionCallbacks, OnConnectionFailedListener { 
    /** 
    * Banner Advert AdMob key. 
    */ 
    private static final String BANNER_ADMOB_UNIT_ID= "XXXXX"; 

    /** 
    * Fullscreen Advert AdMob key. 
    */ 
    private static final String FULLSCREEN_ADMOB_UNIT_ID= "XXXXX"; 

    /** 
    * Google API Client. 
    */ 
    private GoogleApiClient googleApiClient; 

    /** 
    * If currently resolving a sign in error. 
    */ 
    private boolean isResolvingSignInError; 

    /** 
    * Global Leaderboard ID. 
    */ 
    private static final String LEADERBOARD_ID = "XXXXX"; 

    /** 
    * Unique request resolve error ID. 
    */ 
    private static final int REQUEST_RESOLVE_ERROR = 1267; 

    /** 
    * Unique request for achievements ID. 
    */ 
    private static final int REQUEST_ACHIEVEMENTS = 1268; 

    /** 
    * Unique request for leaderboards ID. 
    */ 
    private static final int REQUEST_LEADERBOARD = 1269; 

    /** 
    * Google Analytics Trackers. 
    */ 
    private HashMap<TrackerName, Tracker> trackers = new HashMap<TrackerName, Tracker>(); 

    /** 
    * Google Analytics App Tracker. 
    */ 
    private Tracker appTracker; 

    /** 
    * Google Analytics Global Tracker. 
    */ 
    private Tracker globalTracker; 

    /** 
    * Google Analytics Ecommerce Tracker. 
    */ 
    private Tracker ecommerceTracker; 

    /** 
    * If the game has been started. 
    */ 
    private boolean isStarted = false; 

    /** 
    * Advertisement View. 
    */ 
    protected AdView adView; 

    /** 
    * Interstitial Advertisement. 
    */ 
    protected InterstitialAd interstitialAd; 

    /** 
    * Game View. 
    */ 
    protected View gameView; 

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

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

     this.setTitle("Cheeky Chameleon"); 

     this.appTracker = this.getTracker(TrackerName.APP_TRACKER); 
     this.globalTracker = this.getTracker(TrackerName.GLOBAL_TRACKER); 
     this.ecommerceTracker = this.getTracker(TrackerName.ECOMMERCE_TRACKER); 

     this.appTracker.enableAdvertisingIdCollection(true); 
     this.globalTracker.enableAdvertisingIdCollection(true); 
     this.ecommerceTracker.enableAdvertisingIdCollection(true); 

     AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); 
     config.useAccelerometer = false; 
     config.useCompass = false; 
     config.useWakelock = true; 
     config.hideStatusBar = true; 
     config.useImmersiveMode = true; 

     RelativeLayout layout = new RelativeLayout(this); 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); 

     this.createInterstitialAd(); 

     this.createAdView(); 
     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
     params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); 
     params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); 
     layout.addView(this.adView, params); 

     this.createGameView(config); 
     layout.addView(this.gameView); 

     this.setContentView(layout); 
     this.startAdvertising(); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     GoogleAnalytics.getInstance(this).reportActivityStart(this); 
     GoogleAnalytics.getInstance(this).getLogger() 
     .setLogLevel(LogLevel.INFO); 

     this.googleApiClient = new GoogleApiClient.Builder(this) 
     .addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN) 
     .addApi(Games.API).addScope(Games.SCOPE_GAMES) 
     .addConnectionCallbacks(this) 
     .addOnConnectionFailedListener(this) 
     .build(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     System.out.println("Stop"); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     GoogleAnalytics.getInstance(this).reportActivityStop(this); 
     this.googleApiClient.disconnect(); 
     System.out.println("Destroy"); 
    } 

    /** 
    * Create AdView. 
    * 
    * @return AdView. 
    */ 
    private void createAdView() { 
     this.adView = new AdView(this); 
     this.adView.setAdSize(AdSize.SMART_BANNER); 
     this.adView.setAdUnitId(AndroidLauncher.BANNER_ADMOB_UNIT_ID); 
     this.adView.setId(12398); 
     this.adView.setBackgroundColor(Color.WHITE); 
    } 

    /** 
    * Create fullscreen AdView. 
    */ 
    private void createInterstitialAd() { 
     this.interstitialAd = new InterstitialAd(AndroidLauncher.this); 
     this.interstitialAd.setAdUnitId(AndroidLauncher.FULLSCREEN_ADMOB_UNIT_ID); 

     AdRequest adRequest = new AdRequest.Builder().build(); 
     this.interstitialAd.loadAd(adRequest); 
    } 

    @Override 
    public void loadInterstitialAdvert() { 
     AdRequest adRequest = new AdRequest.Builder().build(); 
     interstitialAd.loadAd(adRequest); 
    } 

    /** 
    * Create GameView. 
    * 
    * @param config AndroidApplicationConfiguration. 
    * @return View. 
    */ 
    private void createGameView(AndroidApplicationConfiguration config) { 
     this.gameView = this.initializeForView(new CheekyChameleon(this), config); 

     this.gameView.setSystemUiVisibility(
       View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
       | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
       | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
       | View.SYSTEM_UI_FLAG_FULLSCREEN 
       | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 

     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
     params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); 
     params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); 
     params.addRule(RelativeLayout.ABOVE, adView.getId()); 
     this.gameView.setLayoutParams(params); 
    } 

    /** 
    * Start Advertising. 
    * 
    * @param adView AdView. 
    */ 
    private void startAdvertising() { 
     AdRequest.Builder adRequestBuilder = new AdRequest.Builder(); 
      AdRequest adRequest = adRequestBuilder.build(); 
      adView.setAdListener(new AdListener() { 
       @Override 
       public void onAdFailedToLoad(int error) { 
        System.out.println("Error: " + error); 
       } 
      }); 
      adView.loadAd(adRequest); 

    } 

    @Override 
    public void setTrackerScreenName(String name) { 
     this.globalTracker.setScreenName(name); 
     this.globalTracker.send(new HitBuilders.AppViewBuilder().build()); 
     System.out.println("Tracking screen: " + name); 
    } 

    /** 
    * Get google analytics tracker. 
    * 
    * @param trackerName TrackerName. 
    * @return Tracker. 
    */ 
    public synchronized Tracker getTracker(TrackerName trackerName) { 
     if (!this.trackers.containsKey(trackerName)) { 
      GoogleAnalytics analytics = GoogleAnalytics.getInstance(this); 

      Tracker tracker = (trackerName == TrackerName.APP_TRACKER) ? analytics 
        .newTracker(R.xml.app_tracker) 
        : (trackerName == TrackerName.GLOBAL_TRACKER) ? analytics 
          .newTracker(R.xml.global_tracker) : analytics 
          .newTracker(R.xml.ecommerce_tracker); 
      tracker.enableAdvertisingIdCollection(true); 
      this.trackers.put(trackerName, tracker); 
     } 

     return this.trackers.get(trackerName); 
    } 


    /** 
    * Enum used to identify the tracker that needs to be used for tracking. 
    * 
    * A single tracker is usually enough for most purposes. In case you do need 
    * multiple trackers, storing them all in Application object helps ensure 
    * that they are created only once per application instance. 
    */ 
    public enum TrackerName { 
     APP_TRACKER, // Tracker used only in this app. 
     GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking. 
     ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company. 
    } 


    @Override 
    public void displayInterstitialAdvert() { 
     if(interstitialAd.isLoaded()) { 
      this.interstitialAd.show(); 
     } else { 
      AdRequest adRequest = new AdRequest.Builder().build(); 
      this.interstitialAd.loadAd(adRequest); 
      this.interstitialAd.show(); 
     } 
    } 

    @Override 
    public void signInGooglePlayServices() { 
     if(!this.isResolvingSignInError) { 
      this.googleApiClient.connect(); 
     } 
    } 

    @Override 
    public void signOutGooglePlayServices() { 
     this.googleApiClient.disconnect(); 
    } 

    @Override 
    public boolean isSignedInGooglePlayServices() { 
     return this.googleApiClient.isConnected(); 
    } 

    @Override 
    public void displayAchievements() { 
     if(this.googleApiClient.isConnected()) { 
      this.startActivityForResult(Games.Achievements.getAchievementsIntent(this.googleApiClient), AndroidLauncher.REQUEST_ACHIEVEMENTS); 
     } else { 
      this.googleApiClient.connect(); 
     } 
    } 

    @Override 
    public void displayLeaderboards() { 
     if(this.googleApiClient.isConnected()) { 
      this.startActivityForResult(Games.Leaderboards.getLeaderboardIntent(this.googleApiClient, 
        AndroidLauncher.LEADERBOARD_ID), AndroidLauncher.REQUEST_LEADERBOARD); 
     } else { 
      this.googleApiClient.connect(); 
     } 
    } 

    @Override 
    public void submitScore(int score) { 
     if(this.googleApiClient.isConnected()) { 
      System.out.println("Submiting score: " + score); 
      Games.Leaderboards.submitScore(this.googleApiClient, AndroidLauncher.LEADERBOARD_ID, score); 
     } 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult result) { 
     if(this.isResolvingSignInError) { 
      return; 
     } else if (result.hasResolution()){ 
      try { 
       this.isResolvingSignInError = true; 
       result.startResolutionForResult(this, AndroidLauncher.REQUEST_RESOLVE_ERROR); 
       System.out.println("Failed to connect to Google Play Services, Resolving"); 
      } catch(SendIntentException exception) { 
       this.googleApiClient.connect(); 
      } 
     } else { 
      GooglePlayServicesUtil.showErrorDialogFragment(result.getErrorCode(), this, AndroidLauncher.REQUEST_RESOLVE_ERROR); 
      this.isResolvingSignInError = false; 
      System.out.println("Failed to connect to Google Play Services: " + result.getErrorCode()); 
     } 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     System.out.println("Connected to Google Play Services"); 
    } 

    @Override 
    public void onConnectionSuspended(int number) { 
     System.out.println("Google Play Services connection suspended"); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == AndroidLauncher.REQUEST_RESOLVE_ERROR) { 
      this.isResolvingSignInError = false; 

      if (resultCode == RESULT_OK) { 
       if (!this.googleApiClient.isConnecting() && 
         !this.googleApiClient.isConnected()) { 
        this.googleApiClient.connect(); 
       } 
      } else { 
       System.out.println("Sign in failed: " + resultCode); 
      } 
     } else if(requestCode == AndroidLauncher.REQUEST_ACHIEVEMENTS) { 
      if (resultCode != RESULT_OK && resultCode != RESULT_CANCELED) { 
       Toast.makeText(this, "Failed to show achivements", Toast.LENGTH_SHORT).show(); 
       System.out.println("Failed to display achievements."); 
      } 
     } 
    } 
} 

Это мой AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.ifs_studios.cheekychameleon.android" 
    android:versionCode="29" 
    android:versionName="0.4.1" > 

    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="21" /> 

    <uses-permission android:name="android.permission.INTERNET"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
    <uses-permission android:name="com.android.vending.BILLING" /> 
    <uses-permission android:name="android.permission.VIBRATE"/> 
    <uses-permission android:name="android.permission.VIBRATE"/> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.WRITE_GSERVICES"/> 


    <application 
     android:allowBackup="false" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name"> 
     <activity 
      android:name="com.ifs_studios.cheekychameleon.android.AndroidLauncher" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" 
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/> 

     <meta-data android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 
     <meta-data 
     android:name="com.google.android.gms.analytics.globalConfigResource" 
     android:resource="@xml/global_tracker" /> 
     <meta-data android:name="com.google.android.gms.games.APP_ID" 
     android:value="@string/app_id" /> 
    </application> 
</manifest> 

С выходом LogCat я понятия не имею, что может быть проблема. Я тестировал это на Xperia U и Xperia Z1, и проблема все еще сохраняется. Спасибо за вашу помощь.

Edit - Дополнительная информация:

Я использую lateset версию LibGDX (1.5.4)

+1

Любой шанс, что вы ссылаетесь на любые текстуры или шейдеры со статическими переменными? Это может вызвать эту проблему. – Tenfour04

+0

Я так не верю, все мои текстуры обрабатываются с помощью AssetManager в LibGDX. – BleedObsidian

+0

'super.onCreate (bundle)' всегда должно быть первым в 'onCreate'. Вы сокращаете его с помощью этого 'isStarted', который может быть проблемой. Во всяком случае, для чего? – Tenfour04

ответ

0

После нескольких дней стресса, я наконец-то исправили проблему. После выполнения backtrace в основном потоке я обнаружил, что программа остановилась при попытке загрузить трекеры Google Analytics. Это нить трассировку:

в com.google.android.gms.analytics.ae.getLogger (Unknown Source)
в com.google.android.gms.analytics.ae.W (Unknown Source)
at com.google.android.gms.analytics.z $ af (Неизвестный источник) at com.google.android.gms.analytics.na (Неизвестный источник)
at com.google.android.gms.analytics. nx (Неизвестный источник)
at com.google.android.gms.analytics.GoogleAnalytics.eZ (Неизвестный источник)
at com.google.android.gms.analytics.GoogleAnalytics. (Неизвестный источник)
на com.google.android.gms.analytics.GoogleAnalytics. (Unknown Source)
на com.google.android.gms.analytics.GoogleAnalytics.getInstance (Unknown Source)

Затем я сделал некоторые исследования на этот результат. Кажется, это ошибка, возникающая при попытке загрузить трекеры из XML-файла.Эта ошибка обсуждается более подробно здесь:

Чтобы предотвратить эту ошибку, я больше не загружать трекеры из своих corrosponding файлов XML, удалив эту строку в AndroidManifest. xml:

<meta-data 
     android:name="com.google.android.gms.analytics.globalConfigResource" 
     android:resource="@xml/analytics_global_config" /> 

Проблема исправлена, спасибо, ребята.

Смежные вопросы