Android-приложение очень медленно перелистывает viewpager и прокручивает программу повторного просмотра, как определить причину? - PullRequest
0 голосов
/ 03 июня 2019

Итак, я застрял в этой проблеме на неделю, когда я запускаю свое приложение, и оно зависает почти на 10 секунд на белом экране, и после этого приложение становится очень медленным.У меня есть навигационное представление снизу с виджером, который загружает четыре фрагмента, некоторые из которых имеют виды переработчика с пользовательскими адаптерами.Каждый раз, когда я провожу пальцем или выбираю другую вкладку, приложение мучительно медленно выбирает новую вкладку.Даже прокрутка вьюблера очень медленная.Странная часть заключается в том, что когда данные отключены, приложение работает просто отлично, а прокрутка в виде пейджера и прокрутка в окне повторного просмотра выполняются достаточно быстро.

Я видел несколько предложений, которые предлагают использовать синтаксический анализ gson для данных json, полученных из Интернета., но прирост производительности был незначительным.Я также попытался viewPager.setOffscreenPageLimit (4);но это не помогло.Все мои сетевые вызовы были помещены в асинхронную задачу, и я использовал StrictMode, чтобы подтвердить это.Приложение также работает нормально на эмуляторе, поэтому проблема заключается только в реальных устройствах всех API, которые я тестировал.

 //First Fragment
public void loadData(final Context context, final boolean b) {

    HurlStack hurlStack = new HurlStack() {
        @Override
        protected HttpURLConnection createConnection(URL url) {
            HttpsURLConnection httpsURLConnection = null;
            try {
                httpsURLConnection = CustomCAHttpsProvider.getHttpsUrlConnection(ServerConstants.LOAD_CHAT_URL, InfosylumApplication.getContext(), R.raw.certificate, false);
            } catch (Exception e) {
                e.printStackTrace();
                Helper.showErrorDialog(e.getMessage(), e.toString(), InfosylumApplication.getContext());
            }
            return httpsURLConnection;
        }
    };

    StringRequest stringRequest = new StringRequest(Request.Method.POST, ServerConstants.LOAD_CHAT_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            mSwipeRefreshLayout.setRefreshing(false);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (isRunning) {
                        loadData(context, b);
                    }
                }
            }, 3000);
            try {
                JSONObject jsonObject = new JSONObject(response).getJSONObject("object");
                TinyDB tinyDB = new TinyDB(context);
                tinyDB.putString(TinyDBConstants.LOCAL_TYPING, "");


                if (jsonObject.has("groupsAndInd")) {
                    final JSONArray array = jsonObject.getJSONArray("groupsAndInd");
                    LinkedHashMap<String, ChatNotification> chatNotificationLinkedHashMap = new LinkedHashMap<>();

                    final JSONArray localChatArray;
                    if (!tinyDB.getString(TinyDBConstants.LOCAL_CHAT_OTHER).isEmpty()) {
                        localChatArray = new JSONArray(tinyDB.getString(TinyDBConstants.LOCAL_CHAT_OTHER));
                    } else {
                        localChatArray = new JSONArray();
                    }

                    ArrayList<String> localChatIds = new ArrayList<>();
                    final ArrayList<String> onlineChatIds = new ArrayList<>();


                    String idsString = "";
                    for (int i = 0; i < localChatArray.length(); i++) {
                        JSONObject foodJson = localChatArray.getJSONObject(i);
                        localChatIds.add(foodJson.getString("id"));
                        idsString += foodJson.getString("id") + "\n";
                    }


                    for (int i = 0; i < array.length(); i++) {
                        JSONObject object = array.getJSONObject(i);

                        List<String> urlList = Arrays.asList(object.getString("seenUsers").split(","));


                        if ((!urlList.contains(PatriceUser.getCurrentUser().getObjectId()) || object.getInt("messageStatus") < (Const.MESSAGE_STATUS_RECEIVED)) && !localChatIds.contains(object.getString("id")) && !object.getString("senderId").equals(PatriceUser.getCurrentUser().getObjectId())) {

                            String id = null, chatType = null;
                            switch (object.getString("chatType")) {
                                case Const.CHAT_TYPE_GROUP:
                                    id = object.getString("groupId");
                                    chatType = Const.CHAT_TYPE_GROUP;
                                    break;
                                case Const.CHAT_TYPE_INDIVIDUAL:
                                    id = object.getString(Const.SENDER_ID);
                                    chatType = Const.CHAT_TYPE_INDIVIDUAL;
                                    break;
                            }

                            boolean found = false;


                            if (chatNotificationLinkedHashMap.containsKey(id)) {
                                ChatNotification chatNotification = chatNotificationLinkedHashMap.get(id);
                                chatNotification.addChatObject(object);
                                chatNotificationLinkedHashMap.put(id, chatNotification);
                            } else {
                                ChatNotification chatNotification = new ChatNotification(context, chatType, id, object);
                                chatNotificationLinkedHashMap.put(id, chatNotification);
                            }


                        }

                        onlineChatIds.add(object.getString("id"));

                    }

                    tinyDB.putString(TinyDBConstants.LOCAL_CHAT_OTHER, array.toString());


                    for (Map.Entry<String, ChatNotification> entry : chatNotificationLinkedHashMap.entrySet()) {
                        String key = entry.getKey();
                        ChatNotification value = entry.getValue();

                        final InfosylumNotification infosylumNotification = new InfosylumNotification(context);
                        infosylumNotification.showNotification(value);
                    }


                }


                try {

                    if (jsonObject.has("groupsAndInd")) {
                        getActualMessages(jsonObject.getJSONArray("groupsAndInd"), jsonObject.getJSONArray("unread"));
                    }

                    if (jsonObject.has("notes")) {
                        loadNotes(jsonObject.getJSONArray("notes"));
                    }


                } catch (NullPointerException ignore) {
                    Helper.showErrorDialog("ignore", ignore.getMessage(), getActivity());
                }


            } catch (JSONException e) {

            } catch (NullPointerException e) {
                //When the user has logged out


        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {


        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("userId", PatriceUser.getCurrentUser().getObjectId());


            params.put("loadGroupsQuery", loadGroupsQuery);


            return params;
        }
    };

    stringRequest.setRetryPolicy(new DefaultRetryPolicy(
            40000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

   VolleySingleton.getInstance(activity).addToRequestQueue(stringRequest);
    stringRequest.setTag(REQUEST_TAG);
    if (requestQueue == null) {
        requestQueue = Volley.newRequestQueue(InfosylumApplication.getContext(), hurlStack);
    }

    requestQueue.add(stringRequest);


}

Другие фрагменты очень похожи в том, как они получают данные, есть также фоновые заданияв приложении, и я думаю, что самое сложное - определить, какой метод вызывает ошибку.Кроме того, об использовании профилировщика не может быть и речи, поскольку используемое устройство имеет API-интерфейс 17. Я просто хотел бы спросить, есть ли способ определить, какой именно метод вызывает медлительность и случайные ANR, которые я получаю?

1 Ответ

0 голосов
/ 03 июня 2019

Глядя на свой код, вы создаете новый HttpURLConnection каждый раз, когда вызываете loadData(), что не нужно. Попробуйте использовать шаблон проектирования Singleton для создания экземпляра httpConnection только один раз.

Здесь: new Handler().postDelayed(new Runnable() { @Override public void run() { if (isRunning) { loadData(context, b); } } }, 3000);

этот код выполняется из loadData(), поэтому существует рекурсивный вызов (этот метод вызывается снова и снова каждые 3 секунды (если isRunning==true)).
В этом случае попробуйте создать все переменные (особенно списки) вне метода this, так что вы будете использовать их повторно, а не каждый раз создавать новый экземпляр.

Когда у вас нет интернета, он работает быстро, потому что вы не выполняете onResponse (который содержит несколько циклов), а только маленький onErrorResponse.

Что вы пытаетесь делать с методом? Может быть, я могу помочь вам, предоставив альтернативное решение для этого.

ОБНОВЛЕНИЕ где вы выполняете асинхронные задачи? Handler выполняет в том же потоке, в котором он был создан? это AsynchTask или это основной поток вызывает loadData()

...