Reputation: 563
I my app I have two tabs. For tabs I use fragments. Each tab has a network call using Volley. For volley error I am using Snackbar to show the error. My problem is, the Snackbar is working well if I am in that particular fragment while the error is triggering. If I go back before the error trigger this error coming.
Logcat..
12-21 09:11:18.782 3707-3707/com.dushanmadushanka.slicdashboard.slicdashboard E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dushanmadushanka.slicdashboard.slicdashboard, PID: 3707
java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
at android.support.design.widget.Snackbar.make(Snackbar.java:181)
at com.dushanmadushanka.slicdashboard.slicdashboard.other.VolleyErrorHandle.handleVolleyErrorThree(VolleyErrorHandle.java:102)
at com.dushanmadushanka.slicdashboard.slicdashboard.fragment.general.GeneralRegionalFragment$4.onErrorResponse(GeneralRegionalFragment.java:288)
at com.android.volley.Request.deliverError(Request.java:617)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:104)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Fragment...
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View lView = inflater.inflate(R.layout.fragment_life_regional, container, false);
getTableJsonData(1, AppConfig.URL_GET, 1, lView);
return lView;
}
Method...
private void getTableJsonData(int currentMonth, String mUrl, int screenType, final View lView) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, newUrl, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (requestQueue != null) {
myList.clear();
lrAdapter.setJsonData(myList);
VolleyErrorHandle.handleVolleyErrorThree(error, progressBar, lView.findViewById(R.id.fragment_life_region_layout));
}
}
});
//AppController.getInstance().addToRequestQueue(stringRequest, TAG_REQ);
requestQueue.add(stringRequest);
stringRequest.setRetryPolicy(new DefaultRetryPolicy(15 * 1000, 1,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
Snackbar....
public static void handleVolleyErrorThree(VolleyError error, ProgressBar p, View view) {
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Snackbar snackbar = Snackbar.make(view, "Please connect to the network!", Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbarView.setBackgroundColor(Color.RED);
snackbar.show();
} else if (error instanceof AuthFailureError) {
Snackbar snackbar = Snackbar.make(view, "Authentication error!", Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbarView.setBackgroundColor(Color.RED);
snackbar.show();
} else if (error instanceof ServerError) {
Snackbar snackbar = Snackbar.make(view, "No data!", Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbarView.setBackgroundColor(Color.RED);
snackbar.show();
} else if (error instanceof NetworkError) {
Snackbar snackbar = Snackbar.make(view, "Network error!", Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbarView.setBackgroundColor(Color.RED);
snackbar.show();
} else if (error instanceof ParseError) {
Snackbar snackbar = Snackbar.make(view, "Database connection error!", Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbarView.setBackgroundColor(Color.RED);
snackbar.show();
}
p.setVisibility(View.GONE);
}
Upvotes: 4
Views: 4330
Reputation: 341
I have found out why this problem occurs, it comes when you are using interfaces to communicate the results of an async call such as making a network request. When you navigate from one tab, it's views are rendered invalid (destroyed). But when the async call finally invokes an interface you defined in the tab you navigated from, the view you provided for your snack bar will no longer be valid, hence it throws an error.
Possible solutions:
Cancel all activities that can invoke a callback in a view you navigated from
Upvotes: 0
Reputation: 29783
You can try using Activity content view as your parameter when calling SnackBar, something like this:
View view = getActivity().findViewById(android.R.id.content);
Snackbar snackbar = Snackbar.make(view, "Please connect to the network!", Snackbar.LENGTH_LONG);
...
snackbar.show();
Upvotes: 3
Reputation: 5705
Seems like you have defined your lView
variable twice in your code. You are using a local final variable lView in your onCreateView() method and trying to pass that same view in your snackbar method. So try passing a valid view in your method and it should work.
final View lView = inflater.inflate(R.layout.fragment_life_regional, container, false)
This is your local variable and then you are trying to access it in your handle volley error method call like this
VolleyErrorHandle.handleVolleyErrorThree(error, progressBar, lView.findViewById(R.id.fragment_life_region_layout));
In the above code lView should be null as the the first one is a local variable and will not be accessible in your second method.
Upvotes: 0