将Activity转换为MainActivity时出现ClassCastException

时间:2017-06-01 08:37:08

标签: java android classcastexception

在将活动投射到我的MainActivity时,我的Android应用中遇到了一个奇怪的问题。我正在使用GeoFences将事件广播到名为NotificationActivity的基本活动。 NotificationActivity用于我使用的所有其他活动,因此当GeoFence触发AlertDialog弹出时。现在,当GeoFence触发并且我处于MainActivity之外的活动时,我需要完成当前活动并对MainActivity执行某个操作(切换到某个选项卡)。在我的Application类中,我正在实现Application.ActivityLifeCycleCallbacks,在onActivityResumed回调中,我将currentActivity设置为恢复活动(我知道静态引用会导致内存泄漏,但我需要修复此问题)。

这是我的应用程序类:

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

}

2 个答案:

答案 0 :(得分:1)

你在别的地方做错了什么

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

在run方法中,活动不是MainActivity,因为您之前会检查它。

答案 1 :(得分:0)

拳头检查

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

这样你就可以摆脱classCastException