2017-06-01 5 views
-3

Ich habe ein seltsames Problem in meiner Android App, wenn ich eine Aktivität in meine MainActivity umwandle. Ich verwende GeoFences, um Ereignisse an eine Basisaktivität namens NotificationActivity zu senden. Die NotificationActivity wird in allen anderen Aktivitäten verwendet, die ich verwende, wenn also ein GeoFence einen AlertDialog auslöst. Wenn nun ein GeoFence ausgelöst wird und ich in einer anderen Aktivität als MainActivity bin, muss ich die aktuelle Aktivität beenden und eine bestimmte Aktion auf der MainActivity ausführen (zu einer bestimmten Registerkarte wechseln). In meiner Application-Klasse implementiere ich die Application.ActivityLifeCycleCallbacks, im OnActivityResumed-Callback setze ich meine currentActivity auf die wiederaufgenommene Aktivität (ich weiß, dass eine statische Referenz Speicherlecks verursacht, aber ich muss das beheben).ClassCastException beim Umwandeln von Aktivität in MainActivity

Hier ist meine Anwendungsklasse:

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; 
} 

Und hier ist meine NotificationActivity (Basis) Aktivität:

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

Sie überprüfen 'if (currentActivity Instanceof MainActivity)', dann gegossen. Und "else" wirfst du es auch: '((MainActivity) currentActivity) .switchTab();'. Warum bist du überrascht, diese Ausnahme zu bekommen? Wenn es keine Instanz von MainActivity ist, kann es nicht in MainActivity umgewandelt werden. –

+0

Verwenden Sie EventBus anstelle der statischen Aktivität Instanz. (Greenrobot EventBus) – hcknl

Antwort

1

Sie etwas falsch auf sonst

tun werden
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); 
    } 
} 

Innerhalb der Run-Methode ist die Aktivität kein MainActivity, wie Sie es vorher überprüfen.

+0

DUH gute Antwort Ich habe das total übersehen! Danke, Mann! – Tripwire

0

Faust Scheck

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

Auf diese Weise erhalten Sie von Classcast befreien

Verwandte Themen