【发布时间】:2019-06-03 09:45:07
【问题描述】:
因此,我在这个问题上被困了一个星期,我启动我的应用程序,它在白屏上冻结了近 10 秒,之后应用程序变得非常慢。我有一个带有 viewpager 的底部导航视图,它加载了四个片段,其中一些片段具有带有自定义适配器的 recyclerviews。每次我滑动或选择不同的标签时,应用程序选择新标签的速度非常慢。即使是 recyclerview 滚动也很慢。奇怪的是,当数据关闭时,应用程序运行正常,viewpager 滑动和 recyclerview 滚动速度足够快。
我看到了一些建议,建议对从在线接收的 json 数据使用 gson 解析,但性能提升可以忽略不计。我也试过 viewPager.setOffscreenPageLimit(4);但这没有帮助。我所有的网络调用都放在了一个 asycntask 上,我已经使用 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?
【问题讨论】:
-
在运行应用程序时尝试在 android studio 中检查您的 logcat。它应该向您显示哪些活动需要很长时间才能响应。
-
我可以推荐使用日志记录的代码(在进入或退出函数时)吗?甚至可以使用自定义的更智能的记录器来收集一些统计数据和资料。
-
进展如何?它解决了你的问题吗?
-
还没有。还在努力中
标签: java android android-viewpager android-strictmode