Эффект ANR при использовании Volley

#android #android-fragments #android-volley #bottomnavigationview #android-anr-dialog

#Android #android-фрагменты #android-volley #bottomnavigationview #android-anr-dialog

Вопрос:

Я пытался решить эту проблему в течение двух дней. К сожалению, улучшения минимальны.

Я использую BottomNavigationView, который переключает фрагменты с помощью getSupportFragmentManager().beginTransaction().replace(...

Каждый фрагмент при создании вызывает API с использованием Volley. пример:

 public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_services, container, false);

        ....

        callAPI();
}
 
 private void callAPI() {
        VolleyUtils.makeJsonObjectRequest(context, ..., new VolleyResponseListener() {

            @Override
            public void onError(String message) {
                  System.out.println("Error: "   message);
            }
            
            @Override
            public void onResponse(String response) {
                  //JSON processing
                  //textView.setText(...);
            }
        }
}
 

VolleyUtils.java:

 public class VolleyUtils {

    public static void makeJsonObjectRequest(Context context, ..., final VolleyResponseListener listener) {
        StringRequest jsonObjectRequest = new StringRequest
                (Request.Method.POST, "API URL", listener::onResponse, error -> listener.onError(error.toString())) {

            @Override
            public byte[] getBody() {
                //DATA
            }

            @Override
            protected Response<String> parseNetworkResponse(NetworkResponse response) {
                try {
                    String jsonString = new String(response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    JSONObject responseObj = new JSONObject(jsonString);
                    jsonString = responseObj.getJSONObject("response").toString();
                    //System.out.println(jsonString); //TODO remove debug line
                    return Response.success(jsonString,
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException | JSONException e) {
                    return Response.error(new ParseError(e));
                }
            }
        };

        // Access the RequestQueue through singleton class.
        VolleySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);
    }
}

 

VolleySingleton.java:

 public class VolleySingleton {
    @SuppressLint("StaticFieldLeak")
    private static VolleySingleton instance;
    private RequestQueue requestQueue;
    @SuppressLint("StaticFieldLeak")
    private static Context ctx;

    private VolleySingleton(Context context) {
        ctx = context;
        requestQueue = getRequestQueue();
    }

    public static synchronized VolleySingleton getInstance(Context context) {
        if (instance == null)
            instance = new VolleySingleton(context);
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null)
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }
}
 

VolleyResponseListener:

 public interface VolleyResponseListener {
    void onError(String message);

    void onResponse(String response);
}
 

Проблема в том, что эффект ANR возникает при переключении фрагментов с использованием BottomNavigationView

Лучшие улучшения, которых мне удалось добиться благодаря:

 APIRunnable apiRunnable = new APIRunnable();
thread = new Thread(apiRunnable);
thread.start();

...

class APIRunnable implements Runnable {
        @Override
        public void run() {
            callAPI();
        }
    }
 

Но при более быстром переключении эффект ANR все равно возникает

I/Choreographer: Skipped 64 frames! The application may be doing too much work on its main thread.

Я действительно больше не знаю, как это решить. Я буду рад любой помощи

Спасибо

Комментарии:

1. Я бы настоятельно рекомендовал перейти на модернизацию из Volley. Вы избавите себя от многих головных болей, которые у вас сейчас возникают

2. @IvanWooll хорошо, дай мне попробовать

3. @IvanWooll это хуже:(

4. @IvanWooll Теперь ANR также происходит в эмуляторе, чего раньше не было

Ответ №1:

Я решил проблему:

Я не понимал, что когда я запрашивал API, я вызывал метод, который генерировал данные POST.

Теперь я вызываю этот метод с new Thread помощью, а затем вызываю API.

Это решило проблему, и даже при быстром переключении все проходит гладко.

Тем не менее, я также переключился с Volley на модернизацию.

Спасибо Ивану за его помощь