I\'m having a problem with a listener in a certain activity.
The problem is that this listener contains an alert.show(); which can be called after we try to push a
Background thread after finishing their networking tasks invokes callback onSuccess()/onFailure() on the main thread. And if at that time, the activity which initiated this background thread task is not in the foreground and you try to use getActivity() in either onSuccess()/onFailure(), it will give you the exception. So try to add this check before doing any UI operation.
if(!((Activity) context).isFinishing())
{
//show alert
}
For API level >= 23 you can use 'lifecycle' property of activity to detect the state of activity. This gives a very compact code. Here is an example code in Kotlin, as class extension:
fun FragmentActivity.isRunning() = lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
// ...
// Here 'myActivity' can be inherited from different activity-like classes,
// for example, from class AppCompatActivity:
if (myActivity.isRunning()) {
Log.d("log", "Activity is running!")
}
I was having 2 activities A & B, I just wanted to know Activity B is running or not from A.
Initially i followed "RunningTaskInfo" for resolving the problem, It was not working 100%.
So i created own solution, I will post my solution. Using HashMap and AtomicBoolean class.
public class ActivityStateTracker {
final private Map<String, AtomicBoolean> mMap = new HashMap<String, AtomicBoolean>();
private static ActivityStateTracker instance = null;
/**
* SingletonClass
* */
private ActivityStateTracker() {
}
public static ActivityStateTracker getInstance(String activityName, boolean defaultVal) {
if(instance == null) {
instance = new ActivityStateTracker();
}
instance.setDefaultValue(activityName, defaultVal);
return instance;
}
private void setDefaultValue(String activityName, boolean defaultVal) {
mMap.put(activityName, new AtomicBoolean(defaultVal));
}
public boolean isRunning(String activityName) {
final AtomicBoolean atomicBool = mMap.get(activityName);
return (mMap.get(activityName) == null) ? false : atomicBool.get();
}
public void setChangeState(String activityName, boolean value) {
final AtomicBoolean atomicBool = mMap.get(activityName);
if(atomicBool == null) {
setDefaultValue(activityName, value);
} else {
atomicBool.set(value);
mMap.put(activityName, atomicBool);
}
}
}
Now in Activity B.
public static final String TAG = "EditScreenPopupActivity";
static ActivityStateTracker mActivityState = ActivityStateTracker.getInstance(TAG, false);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityState.setChangeState(TAG, true);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_traslucent);
}
@Override
protected void onDestroy() {
mActivityState.setChangeState(TAG, false);
super.onDestroy();
}
Now in Activity A.
public static final String TAG = "ToolTipPopupActivity";
static ActivityStateTracker mActivityState = ActivityStateTracker.getInstance(TAG, false);
/** Check Edit screen activity is running or not? */
if(mActivityState.isRunning("EditScreenPopupActivity")) {
finish();
}
......................................
This solution is working properly in my case.. I hope it will help you as well..
ArrayList<String> runningactivities = new ArrayList<String>();
ActivityManager activityManager = (ActivityManager)getBaseContext().getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (int i1 = 0; i1 < services.size(); i1++) {
runningactivities.add(0,services.get(i1).topActivity.toString());
}
if(runningactivities.contains("ComponentInfo{com.app/com.app.main.MyActivity}")==true){
Toast.makeText(getBaseContext(),"Activity is in foreground, active",1000).show();
alert.show()
}
This way you will know if the pointed activity is the current visible activity, else your alert will not display.
This will only work when we navigate between two activities without finish.
Yes you can check if activity is active: Refreshing an Activity from service when Active
Also, if your are not doing anything when your Activity in not active, then you should probably unregister the listener when your Activity deactivates.
This happens when the Activity will be going through its destruction when the background thread finishes its work and tries to show a Dialog.
This exeption is rare to reproduce but happens when we do some async task / background operation and want to display a dialog with Activity context and in the mean while our activity is destroying itself due to some reason.
Android OS should handle this situation, but as of now it does not.
so before calling your dialog just check if activity is running and not in its destruction phase.
if(!isFinishing()){
callDialog();
}