2017-06-01 55 views
-3

将活动强制转换为我的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); 
} 

}

+3

你检查'如果(currentActivity的instanceof MainActivity)',然后投放。 'else'也可以投射它:'((MainActivity)currentActivity).switchTab();'。为什么你很惊讶得到这个例外?如果它不是'MainActivity'的实例,那么它不能转换为'MainActivity'。 –

+0

使用EventBus代替静态活动实例。(Greenrobot EventBus) – hcknl

回答

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

在运行方法中,活动不是MainActivity,因为您之前检查过它。

+0

DUH很好的回答我完全忽略了那个!谢啦! – Tripwire

0

拳检查

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

这样你将摆脱ClassCastException异常

相关问题