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);
}
}
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. –
Verwenden Sie EventBus anstelle der statischen Aktivität Instanz. (Greenrobot EventBus) – hcknl