java - AsyncTask 中的某些内容阻塞了 UI - 导致界面短暂停止

标签 java android

我有一个通过 SQLite 使用缓存数据填充的 ListView 。加载完成后。在后台,我检查新数据并从 MySQL 数据库获取返回的 JSON 结果。

在我的这个后台taskonPostExecute中,当运行此代码时(下面的代码),并且当它被循环时(最多50个循环) ,UI 线程被阻塞,并且无法滚动 ListView。这是代码:

if (result.length() != 0) {
                JSONArray jArray = new JSONArray(result);
                JSONObject json_data = null;

                for (int ii = 0; ii < jArray.length(); ii++) {
                    json_data = jArray.getJSONObject(ii);

                    item = json_data.getString("item");
                    cat = json_data.getString("category");
                    user = json_data.getString("username");
                    userId = json_data.getLong("user_id");
                    review = json_data.getString("review");
                    reviewId = json_data.getLong("review_id");
                    itemId = json_data.getLong("item_id");
                    commentCount = json_data.getLong("commentCount");
                    url = json_data.getString("name");
                    url = pathUrl + url; // for profile icon
                    date = json_data.getString("date");
                    rating = json_data.getDouble("rating");
                    upVote = json_data.getLong("good");
                    wiki = json_data.getString("wiki");


                    watchItems.add(item);
                    watchCats.add(cat);
                    watchUsers.add(user);
                    watchReviews.add(review);
                    watchUrl.add(url);
                    watchDateList.add(date);
                    watchWikiList.add(wiki);

                    watchItemIdList.add(String.valueOf(itemId));
                    watchUserIds.add(String.valueOf(userId));
                    watchReviewId.add(String.valueOf(reviewId));
                    watchRating.add(String.valueOf(rating));
                    watchCommentCount.add(String.valueOf(commentCount));
                    watchUpVote.add(String.valueOf(upVote));

                    Rateit.haveFollowing = "1";

                    if (Rateit.isUserLoggedIn == true) {
                        boolean oldReview = datasource
                                .getReviewIds(reviewId);
                        if (!oldReview) {
                            // Cache Network Items
                            datasource.createTrendWatch(itemId, item,
                                    review, reviewId, cat, user,
                                    String.valueOf(userId), url, date,
                                    commentCount, rating, upVote, 0,
                                    wiki);  
                        }
                    }


                        FollowingItems wti = new FollowingItems(
                                Long.valueOf(watchItemIdList.get(i)),
                                watchItems.get(i), watchCats.get(i),
                                watchReviews.get(i),
                                Long.valueOf(watchReviewId.get(i)),
                                watchUsers.get(i),
                                Long.valueOf(watchUserIds.get(i)),
                                watchUrl.get(i), watchDateList.get(i),
                                Long.valueOf(watchCommentCount.get(i)),
                                Double.valueOf(watchRating.get(i)),
                                Long.valueOf(watchUpVote.get(i)),
                                watchWikiList.get(i++));
                        watchingListObject.add(wti);

                }
            }

为什么会发生这种情况?我该如何阻止我的代码来防止这种情况发生?我可以做一些优化吗?

编辑:下面有人请求完整的任务代码。

Below repeats the code above but in context with entire task.

    public static class FollowingTask extends AsyncTask<String, String, Void> {
        protected InputStream is = null;
        protected String result = "";
        protected String userId;
        protected ArrayList<FollowingItems> watchingListObject;
        protected Context mContext;

        public FollowingTask(Context context) {
            mContext = context;
        }

        @Override
        protected void onPreExecute() {
            if (mContext != null && (fromRefresh == false)) {
                ((MainFragmentActivity) mContext)
                        .setSupportProgressBarIndeterminateVisibility(true);
            }

            resetLists();

            if (PrefActivity.getUserLoggedInStatus(mContext) == true) {
                userId = PrefActivity.getLoggedInUserId(mContext);
            } else {
                userId = "-1";
            }

            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(String... params) {
            datasource.purgeItemWatchingTable();
            Log.d("1", "Back");
            String url_select = "http://www.---.info/includes_mc_php/featured_watching.php";

            HttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url_select);
            ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
            param.add(new BasicNameValuePair("user_id", userId));
            param.add(new BasicNameValuePair("v2", "true"));



            try {
                httpPost.setEntity(new UrlEncodedFormEntity(param));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();

                // read content
                is = httpEntity.getContent();

            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(is));
                StringBuilder sb = new StringBuilder();
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();

            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        protected void onPostExecute(Void v) {

            String pathUrl = Rateit.PROFILE_PIC_URL;
            String item, cat, user, review, url, date, following, wiki;
            long itemId, reviewId, userId, commentCount, upVote;
            double rating;
            int i = 0;
            watchingListObject = new ArrayList<FollowingItems>();


            try {
                String c = String.valueOf(result.charAt(0));

                if (c.equals("{")) {
                    JSONObject jsonObject = new JSONObject(result);
                    following = jsonObject.getString("following");
                    if (following.equals("0")) {
                        Rateit.haveFollowing = "0";
                    }

                } else {

                    if (result.length() != 0) {
                        JSONArray jArray = new JSONArray(result);
                        JSONObject json_data = null;

                        for (int ii = 0; ii < jArray.length(); ii++) {
                            json_data = jArray.getJSONObject(ii);

                            item = json_data.getString("item");
                            cat = json_data.getString("category");
                            user = json_data.getString("username");
                            userId = json_data.getLong("user_id");
                            review = json_data.getString("review");
                            reviewId = json_data.getLong("review_id");
                            itemId = json_data.getLong("item_id");
                            commentCount = json_data.getLong("commentCount");
                            url = json_data.getString("name");
                            url = pathUrl + url; // for profile icon
                            date = json_data.getString("date");
                            rating = json_data.getDouble("rating");
                            upVote = json_data.getLong("good");
                            wiki = json_data.getString("wiki");


                            watchItems.add(item);
                            watchCats.add(cat);
                            watchUsers.add(user);
                            watchReviews.add(review);
                            watchUrl.add(url);
                            watchDateList.add(date);
                            watchWikiList.add(wiki);

                            watchItemIdList.add(String.valueOf(itemId));
                            watchUserIds.add(String.valueOf(userId));
                            watchReviewId.add(String.valueOf(reviewId));
                            watchRating.add(String.valueOf(rating));
                            watchCommentCount.add(String.valueOf(commentCount));
                            watchUpVote.add(String.valueOf(upVote));

                            Rateit.haveFollowing = "1";

                            if (Rateit.isUserLoggedIn == true) {
                                boolean oldReview = datasource
                                        .getReviewIds(reviewId);
                                if (!oldReview) {
                                    // Cache Network Items
                                    datasource.createTrendWatch(itemId, item,
                                            review, reviewId, cat, user,
                                            String.valueOf(userId), url, date,
                                            commentCount, rating, upVote, 0,
                                            wiki);  
                                }
                            }


                                FollowingItems wti = new FollowingItems(
                                        Long.valueOf(watchItemIdList.get(i)),
                                        watchItems.get(i), watchCats.get(i),
                                        watchReviews.get(i),
                                        Long.valueOf(watchReviewId.get(i)),
                                        watchUsers.get(i),
                                        Long.valueOf(watchUserIds.get(i)),
                                        watchUrl.get(i), watchDateList.get(i),
                                        Long.valueOf(watchCommentCount.get(i)),
                                        Double.valueOf(watchRating.get(i)),
                                        Long.valueOf(watchUpVote.get(i)),
                                        watchWikiList.get(i++));
                                watchingListObject.add(wti);

                                Log.d("1", "Post 2");
                        }
                    } else {
                        Rateit.haveFollowing = "2";
                    }
                }
            } catch (JSONException e1) {
                e1.printStackTrace();
                Rateit.haveFollowing = "2";
            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Log.d("1", "Post COMPLETE");
            mPullRefreshListView.onRefreshComplete();

            // Reset Trending List on Pull-to-Refresh
            if (mContext != null) {

                if (watchUsers.size() == 0) {
                    l.setVisibility(View.VISIBLE);
                    tv.setTypeface(TypeFace.get(mContext, Rateit.BPREPLAY));
                } else {
                    l.setVisibility(View.GONE);
                }

                if (mContext != null) {

                    listView.setAdapter(null);

                    if (watchItems.size() > 0) {
                        wAdapter = new FollowingAdapter(mContext,
                                watchingListObject, TypeFace.get(mContext,
                                        Rateit.BPREPLAY), TypeFace.get(
                                        mContext, Rateit.ROBOTO_LIGHT),
                                TypeFace.get(mContext, Rateit.ROBOTO_THIN),
                                TypeFace.get(mContext, Rateit.ROBOTO_REGULAR));
                        listView.setAdapter(wAdapter);
                    }

                }
            }

            if (mContext != null && (fromRefresh == false)) {
                ((MainFragmentActivity) mContext)
                        .setSupportProgressBarIndeterminateVisibility(false);
                MainFragmentActivity.dismissDialog(mContext);

            }

            fromRefresh = false;

        }
    }

最佳答案

onPostExecute 在 UI 线程上运行。它会阻塞 UI。 doInBackground 在后台运行。您应该在 doInBackground 中执行繁重的操作(而不是在 onPostExecute 中)

解决方案:您应该将解析等从onPostExecute移至doInBackground,并使用onPostExecute仅将处理后的信息绑定(bind)到用户界面。

关于java - AsyncTask 中的某些内容阻塞了 UI - 导致界面短暂停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21010566/

相关文章:

java - 如何让按钮永久不可点击

java - AWS EMR Spark - 获取 CSV 并与 SparkSql api 一起使用

android - 应用关闭时收到通知

android - 由于错误 2,GooglePlayServices 不可用

java - 未定义 getDeclaredField 方法

java - jackson :从 json 中删除一些值并保留一些空值

android - onBackPressed() 的问题不是刷新 fragment

Android:如何在软输入/键盘上捕获长按事件?

android:- 如何将图像从 Assets 复制到 SD 卡?

java - Tomcatembedded 不会抛出 FAILED LifeCycleState