Description:
Investigating for a while, I came to find next line code:
handler.removeCallbacksAndMessages(null);
I've tried it and it couldn't solve my problem. This is the error I get:
java.lang.IllegalStateException: Fragment fragment_languages{f33796} not attached to a context.
at androidx.fragment.app.Fragment.requireContext(Fragment.java:696)
at androidx.fragment.app.Fragment.getResources(Fragment.java:760)
at com.example.ui.INICIO.CATEGORIAS.LANGUAGES.fragment_languages.fillRecycler4(fragment_languages.java:173)
at com.example.ui.INICIO.CATEGORIAS.LANGUAGES.fragment_languages.access$200(fragment_languages.java:21)
at com.example.ui.INICIO.CATEGORIAS.LANGUAGES.fragment_languages$3.run(fragment_languages.java:61)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6694)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
I am calling three handlers that loads items into three different recycler views and at different times (this is because, if i load them without waiting, app crashes for using so much memory or something like that).
Problem:
A "troll" user can just get into my app,then get into this fragment in which I have my 4 handlers and press back button once he gets in and this will crash my app too. That's why I want to stop handlers (when pressing back button).
What can I do to repair this error?
What you need to know:
My fragment with handlers is inside an activity (of course). The back button is in the activity (not in the fragment).
"Fragment languages" JAVA code:
father p = new father();
fillRecycler1();
p.handler.postDelayed(new Runnable() {
@Override
public void run() {
fillRecycler2();
}
},1500);
p.handler.postDelayed(new Runnable() {
@Override
public void run() {
fillRecycler3();
}
},2500);
p.handler.postDelayed(new Runnable() {
@Override
public void run() {
fillRecycler4();
}
},3500);
Activity (with back button) Code:
@Override
public void onBackPressed(){
if(p.contador == 0){
Intent intent = new Intent(categorias.this, MainActivity.class);
finish();
startActivity(intent);
p.handler.removeCallbacksAndMessages(null);
p.contador++;
p.handler.postDelayed(new Runnable(){
@Override
public void run(){
p.contador = 0;
}
},500);
}
}
Edit (father class java code):
public class father{
public int contador = 0;
public String aux = null;
public Handler handler = new Handler();
public Window window;
}
You can just skip method call if fragment's view
is destroyed (fragment destroyed or it is in backstack). There is getView() method
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(getView() != null){
fillRecycler2();
}
}
},1500);
If you use hide/show methods of FragmentTransaction
you can use isVisible() method of Fragment
, because hidden fragments view
is View.GONE (not null
)