將活動強制轉換爲我的MainActivity時,我的Android應用程序出現奇怪的問題。我正在使用GeoFences將事件廣播到名爲NotificationActivity的基本活動。 NotificationActivity用於我使用的所有其他活動,因此當GeoFence觸發AlertDialog時彈出。現在,當GeoFence觸發並且我處於MainActivity以外的活動中時,我需要完成當前活動並對MainActivity執行特定操作(切換到某個選項卡)。在我的應用程序類中,我實現了Application.ActivityLifeCycleCallbacks,在onActivityResumed回調中,我將currentActivity設置爲恢復的活動(我知道靜態引用導致內存泄漏,但我需要修復此問題)。將活動強制轉換爲MainActivity時出現ClassCastException
這裏是我的應用程序類:
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;
}
這是我的NotificationActivity(基地)活動:
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);
}
}
你檢查'如果(currentActivity的instanceof MainActivity)',然後投放。 'else'也可以投射它:'((MainActivity)currentActivity).switchTab();'。爲什麼你很驚訝得到這個例外?如果它不是'MainActivity'的實例,那麼它不能轉換爲'MainActivity'。 –
使用EventBus代替靜態活動實例。(Greenrobot EventBus) – hcknl