2017-06-01 1 views
-3

Je rencontre un problème étrange dans mon application Android lorsque je lance une activité sur ma MainActivity. J'utilise GeoFences pour diffuser des événements dans une activité de base appelée NotificationActivity. Le NotificationActivity est utilisé dans toutes les autres activités que j'utilise donc quand un GeoFence déclenche un AlertDialog apparaît. Maintenant, quand un GeoFence se déclenche et que je suis dans une activité autre que MainActivity, j'ai besoin de terminer l'activité en cours et de faire une certaine action sur MainActivity (passer à un certain onglet). Dans ma classe Application, j'implémente Application.ActivityLifeCycleCallbacks, dans le rappel onActivityResumed, j'ai défini mon currentActivity sur l'activité reprise (je sais qu'une référence statique provoque des fuites de mémoire mais j'ai besoin de résoudre ce problème).ClassCastException lors de la conversion de l'activité en MainActivity

Voilà ma classe d'application:

private static Activity currentActivity; 

@Override 
public void onCreate() { 
    super.onCreate(); 

    // Setup Fabric 
    if (AppConfig.getEnvironment() != AppConfig.Environment.Development) { 
     Fabric.with(this, new Crashlytics(), new Answers()); 
    } 

    // Init realm 
    Realm.init(this); 

    // Init Firebase 
    FirebaseApp.initializeApp(this); 

    if (AppConfig.getEnvironment() == AppConfig.Environment.Development) { 
     // Init Stetho with realm plugin 
     Stetho.initialize (
       Stetho.newInitializerBuilder(this) 
         .enableDumpapp(Stetho.defaultDumperPluginsProvider(this)) 
         .enableWebKitInspector(RealmInspectorModulesProvider.builder(this).build()) 
         .build()); 
    } 

    registerActivityLifecycleCallbacks(this); 
} 

@Override 
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 
    Log.d(Constants.DEBUG, "Activity created: " + activity.toString()); 
} 

@Override 
public void onActivityStarted(Activity activity) { 
    Log.d(Constants.DEBUG, "Activity started: " + activity.toString()); 
} 

@Override 
public void onActivityResumed(Activity activity) { 
    Log.d(Constants.DEBUG, "Activity resumed: " + activity.toString()); 
    currentActivity = activity; 
} 

@Override 
public void onActivityPaused(Activity activity) { 
    Log.d(Constants.DEBUG, "Activity paused: " + activity.toString()); 
} 

@Override 
public void onActivityStopped(Activity activity) { 
    Log.d(Constants.DEBUG, "Activity stopped: " + activity.toString()); 
} 

@Override 
public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 
    Log.d(Constants.DEBUG, "Activity SaveInstanceState: " + activity.toString()); 
} 

@Override 
public void onActivityDestroyed(Activity activity) { 
    Log.d(Constants.DEBUG, "Activity Destroyed: " + activity.toString()); 
} 

public static Activity getCurrentActivity() { 
    return currentActivity; 
} 

Et voici mon activité NotificationActivity (base):

public abstract class NotificationActivity extends AppCompatActivity { 

private BroadcastReceiver onNoticeWithinPoi = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     abortBroadcast(); 
     Bundle bundle = intent.getExtras(); 
     if (bundle != null) { 
      Realm realm = Realm.getDefaultInstance(); 
      Poi poi = realm.where(Poi.class).equalTo("ref", bundle.getString(Constants.POI_KEY_REF)).findFirst(); 
      showAlertWithinPoi(context, poi); 
     } 
    } 
}; 

private BroadcastReceiver onNoLocationProviderSet = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     warnUserNoLocationProviderSet(); 
    } 
}; 

private BroadcastReceiver onNoticeOutOfRange = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     abortBroadcast(); 
     alertNoticeOutOfRange(); 
    } 
}; 

public Fragment getActiveFragment() { 
    if (getFragmentManager().getBackStackEntryCount() == 0) { 
     return null; 
    } 

    String tag = getFragmentManager().getBackStackEntryAt(getFragmentManager().getBackStackEntryCount() - 1).getName(); 
    return getFragmentManager().findFragmentByTag(tag); 
} 

private void showAlertWithinPoi(final Context context, final Poi poi) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(this); 
    builder.setTitle(getString(R.string.poi_popup_title)); 
    builder.setMessage(getString(R.string.poi_popup_subtitle)); 
    builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      Game currentGame = Helper.getCurrentGame(context); 
      Game poiGame = null; 

      Realm realm = Realm.getDefaultInstance(); 
      for (Game game : realm.where(Game.class).findAll()) { 
       for (Tag tag : game.tags) { 
        if (tag.poi.ref.equals(poi.ref)) { 
         poiGame = game; 
         break; 
        } 
       } 

       if (poiGame != null) { 
        break; 
       } 
      } 

      if (poiGame != null && poiGame.ref.equals(currentGame.ref)) { 
       realm.beginTransaction(); 
       currentGame.lastSeenPoi = poi.ref; 
       realm.commitTransaction(); 
       checkCurrentActivity(); 
      } else if (poiGame != null && !poiGame.ref.equals(currentGame.ref)) { 
       showAlertDifferentGame(context, poiGame, poi); 
      } 
     } 
    }); 

    builder.setNegativeButton(getString(R.string.later), null); 
    builder.setIcon(R.drawable.poi_unvisited); 
    builder.create().show(); 
} 

private void showAlertDifferentGame(final Context context, final Game game, final Poi poi) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(context); 
    builder.setTitle(getString(R.string.game_switch_title)); 
    builder.setMessage(getString(R.string.game_switch_message) + " " + LanguageHelper.getGameTitle(game) + " ?"); 
    builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      Realm realm = Realm.getDefaultInstance(); 
      realm.beginTransaction(); 
      game.lastSeenPoi = poi.ref; 
      realm.commitTransaction(); 

      SharedPreferencesHelper.saveString(context, Constants.PREF_SELECTED, game.ref); 
      GeofenceService.updateGeoFences(game, context); 
      checkCurrentActivity(); 
     } 
    }); 
    builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      checkCurrentActivity(); 
     } 
    }); 
    builder.create().show(); 
} 

private void checkCurrentActivity() { 
    final Activity currentActivity = GeoFortApplication.getCurrentActivity(); 
    if (currentActivity instanceof MainActivity) { 
     ((MainActivity) currentActivity).switchTab(); 
    } else { 
     currentActivity.finish(); 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Log.d(Constants.DEBUG, "CurrentActivity: " + currentActivity.toString()); 
        ((MainActivity) currentActivity).switchTab(); 
       } catch (ClassCastException e) { 
        Log.e(Constants.EXCEPTION, e.getLocalizedMessage()); 
       } 
      } 
     }, 5000); 
    } 
} 


private void alertNoticeOutOfRange() { 
    new AlertDialog.Builder(this) 
      .setTitle(R.string.error_location_not_close_enough_title) 
      .setMessage(R.string.error_location_not_close_enough_alert) 
      .setPositiveButton(R.string.ok, null) 
      .setIcon(R.drawable.ic_launcher) 
      .show(); 
} 

private void warnUserNoLocationProviderSet() { 
    new AlertDialog.Builder(this) 
      .setTitle(R.string.error_location_not_available_title) 
      .setMessage(R.string.error_location_services_not_available_text) 
      .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        // TODO no user location set? 
       } 
      }) 
      .setIcon(null) 
      .show(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    IntentFilter filterWithinPoi = new IntentFilter(Constants.NOTIFICATION_WITHIN_POI); 
    filterWithinPoi.setPriority(2); 
    registerReceiver(onNoticeWithinPoi, filterWithinPoi); 

    IntentFilter filterOutOfRange = new IntentFilter(Constants.NOTIFICATION_LOCATION_OUT_OF_RANGE); 
    filterOutOfRange.setPriority(2); 
    registerReceiver(onNoticeOutOfRange, filterOutOfRange); 

    IntentFilter filterLocationProviderOff = new IntentFilter(Constants.NOTIFICATION_LOCATION_PROVIDER_OFF); 
    registerReceiver(onNoLocationProviderSet, filterLocationProviderOff); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 

    unregisterReceiver(onNoticeWithinPoi); 
    unregisterReceiver(onNoticeOutOfRange); 
    unregisterReceiver(onNoLocationProviderSet); 
} 

}

+3

vous vérifiez si '(CurrentActivity instanceof MainActivity)', puis convertion. Et 'else' vous le lancez aussi:' ((MainActivity) currentActivity) .switchTab(); '. Pourquoi êtes-vous surpris d'obtenir cette exception? S'il ne s'agit pas d'une instance de MainActivity, il ne peut pas être converti en MainActivity. –

+0

Utilisez plutôt EventBus instance d'activité statique. (Greenrobot EventBus) – hcknl

Répondre

1

vous faites quelque chose de mal sur autre

private void checkCurrentActivity() { 
    final Activity currentActivity = GeoFortApplication.getCurrentActivity(); 
    if (currentActivity instanceof MainActivity) { 
     ((MainActivity) currentActivity).switchTab(); 
    } else { 
     currentActivity.finish(); 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Log.d(Constants.DEBUG, "CurrentActivity: " + currentActivity.toString()); 
        ((MainActivity) currentActivity).switchTab(); 
       } catch (ClassCastException e) { 
        Log.e(Constants.EXCEPTION, e.getLocalizedMessage()); 
       } 
      } 
     }, 5000); 
    } 
} 

Dans la méthode run, l'activité n'est pas MainActivity, comme vous l'avez déjà vérifié.

+0

DUH bonne réponse J'ai totalement négligé celui-là! Merci mec! – Tripwire

0

check Fist

if (activity instanceOf MainActivity){ 
    // do typecast here 
}else{ 
    // you should which which instance you have 
} 

De cette façon, vous vous débarrasser de ClassCastException