在嵌套片段中运行多个异步任务时暂停线程,导致应用程序变慢

13

我在嵌套的片段中调用Web服务,这些片段具有TabLayoutViewPager,并使用AsyncTask。 我已尝试通过在每个FragmentonResume方法中调用它们来使用AsyncTasks

new FetchAllData(getActivity()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

并且

new FetchAllData(getActivity()).execute();

一切都很好,但我遇到了许多问题:

  • 应用程序无任何对话框停止工作,但在日志中显示suspending all threads

  • 当我们从图像所示的另一个活动转到此嵌套标签布局和视图分页器的片段时,除工具栏外,所有内容都会在3至5秒内变为空白。 突然,它们就和完整的数据一起出现了。

  • 当我们从同一活动的另一个片段调用此片段时,它会在那里冻结,并突然打开该片段。

希望您已经理解了我的所有问题,如果没有,请通知我。

堆栈跟踪如下:

1-29 12:10:49.580 10853-10863/com.cws.advisorymandi W/art: Suspending all threads took: 10.409ms
 01-29 12:10:49.707 10853-10853/com.cws.advisorymandi D/cr_Ime: [InputMethodManagerWrapper.java:27] Constructor
 01-29 12:10:49.711 10853-10853/com.cws.advisorymandi D/cr_Ime: [ImeAdapter.java:241] attach
 01-29 12:10:49.711 10853-10853/com.cws.advisorymandi W/art: Attempt to remove local handle scope entry from IRT, ignoring
 01-29 12:10:49.716 10853-10853/com.cws.advisorymandi W/AwContents: onDetachedFromWindow called when already detached. Ignoring
 01-29 12:10:49.717 10853-10853/com.cws.advisorymandi D/cr_Ime: [InputMethodManagerWrapper.java:56] isActive: false
 01-29 12:10:49.726 10853-10853/com.cws.advisorymandi W/art: Attempt to remove local handle scope entry from IRT, ignoring
 01-29 12:10:49.726 10853-10853/com.cws.advisorymandi W/art: Attempt to remove local handle scope entry from IRT, ignoring
 01-29 12:10:49.812 10853-10853/com.cws.advisorymandi D/cr_Ime: [ImeAdapter.java:241] attach
 01-29 12:10:49.832 10853-10853/com.cws.advisorymandi D/cr_Ime: [ImeAdapter.java:241] attach
 01-29 12:10:49.833 10853-10853/com.cws.advisorymandi I/Choreographer: Skipped 58 frames!  The application may be doing too much work on its main thread.
 01-29 12:10:50.075 10853-10853/com.cws.advisorymandi W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 10853
 01-29 12:10:50.610 10853-10863/com.cws.advisorymandi W/art: Suspending all threads took: 43.636ms
 01-29 12:10:50.621 10853-10853/com.cws.advisorymandi I/Ads: Scheduling ad refresh 60000 milliseconds from now.
 01-29 12:10:50.630 10853-10853/com.cws.advisorymandi I/Ads: Ad finished loading.

Fragment.java

public class IndicesFragment extends android.support.v4.app.Fragment implements SwipeRefreshLayout.OnRefreshListener {
public static String imagepath = null;
public static FetchAllData myTask;
static ArrayList<EquityDetails> catListDao = new ArrayList<EquityDetails>();
static ArrayList<EquityDetails> catListDao1 = new ArrayList<EquityDetails>();
static int count = 0;
static int count1 = 0;
ListView list;
ImageView progressBar;
View view;
Activity act;
AdvisorsAdapter adapter;
TextView empty_text;
AnimatorSet set;
JSONArray jsonArray;
SwipeRefreshLayout swipeRefreshLayout;
private boolean isViewShown = false;

public static IndicesFragment newInstance() {
    return new IndicesFragment();
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        isViewShown = true;
        if (adapter != null) {
            adapter.filter("");
        }
    } else {
        isViewShown = false;
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.equity_activity, container, false);
    act = this.getActivity();
    Constants.check_fragment_visible = 1;
    count++;
    setHasOptionsMenu(true);
    list = (ListView) view.findViewById(R.id.list_equity);
    empty_text = (TextView) view.findViewById(R.id.empty);
    swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
    progressBar = (ImageView) view.findViewById(R.id.progressBar);
    set = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(), R.animator.fadein);
    set.setTarget(progressBar);
    progressBar.setVisibility(View.GONE);
    if (Utils.isNetworkAvailable(getActivity())) {
        if (catListDao.size() > 0) {
            adapter = new AdvisorsAdapter(act, R.layout.custom_equity, catListDao, 0);
            list.setAdapter(adapter);
        } else {
            if (!isViewShown) {
                new FetchAllData(getActivity(), 3).execute();
            }
        }
    } else {
        CustomToast toast = new CustomToast(getActivity(), "There is no internet connection!");
    }
    swipeRefreshLayout.setOnRefreshListener(this);
    return view;
}


public void onActivityCreated(Bundle savedInstanceState1) {
    super.onActivityCreated(savedInstanceState1);
}

@Override
public void onResume() {
    super.onResume();
    Constants.check_fragment_visible = 1;
    if (Constants.check_reload) {
        if (Utils.isNetworkAvailable(getActivity())) {
            new FetchAllData(getActivity(), 3).execute();
        } else {
            CustomToast toast = new CustomToast(getActivity(), "There is no internet connection!");
        }
    }
    if (adapter != null) adapter.notifyDataSetChanged();

}

@Override
public void onRefresh() {
    if (Utils.isNetworkAvailable(getActivity())) {
        new FetchAllData(getActivity(), 3).execute();
    } else {
        CustomToast toast = new CustomToast(getActivity(), "There is no internet connection!");
    }
}


public void doChange(String queryText) {
    if (queryText != null) {
        if (adapter != null)
            adapter.filter(queryText);
    }
}

public void parseJSON(String result) {
    if (result != null) {
        JSONObject jsonObject;
        try {
            catListDao = new ArrayList<EquityDetails>();
            jsonObject = new JSONObject(result);
            jsonArray = jsonObject.getJSONArray("list");

            Log.d("Length ", "" + jsonArray.length());
            for (int i = 0; i < jsonArray.length(); i++) {
                EquityDetails allDirectory = new EquityDetails();
                allDirectory.setEntry_value(jsonArray.getJSONObject(i).getString("entry"));
                String value1 = jsonArray.getJSONObject(i).getString("entry");
                String value2 = jsonArray.getJSONObject(i).getString("tgt_1");
                allDirectory.setSerial_value(jsonArray.getJSONObject(i).getString("sl"));
                allDirectory.setTg_value1(jsonArray.getJSONObject(i).getString("tgt_1"));
                allDirectory.setTg_value2(jsonArray.getJSONObject(i).getString("tgt_2"));
                allDirectory.setPosted_by(jsonArray.getJSONObject(i).getString("posted_by"));
                allDirectory.setMainTitle_value(jsonArray.getJSONObject(i).getString("script"));
                allDirectory.setMain_subTitle_value(jsonArray.getJSONObject(i).getString("exchange"));
                allDirectory.setRating_value(jsonArray.getJSONObject(i).getString("rating"));
                allDirectory.setReview_value(jsonArray.getJSONObject(i).getString("review"));
                imagepath = jsonArray.getJSONObject(i).getString("advisor_image");
                Log.d("Comminh Image ", "" + jsonArray.getJSONObject(i).getString("advisor_image"));
                allDirectory.setImage1(jsonArray.getJSONObject(i).getString("advisor_image"));
                allDirectory.setImage2(jsonArray.getJSONObject(i).getString("script_image"));
                allDirectory.setBuy(jsonArray.getJSONObject(i).getString("buy_sentiment"));
                allDirectory.setSell(jsonArray.getJSONObject(i).getString("sell_sentiment"));
                allDirectory.setRecommend(jsonArray.getJSONObject(i).getString("recommendation"));
                allDirectory.setPosted_date(jsonArray.getJSONObject(i).getString("posted_date"));
                allDirectory.setCall_id(jsonArray.getJSONObject(i).getString("call_id"));
                allDirectory.setExpiry_date(jsonArray.getJSONObject(i).getString("expiry_date"));
                allDirectory.setBroker_name(jsonArray.getJSONObject(i).getString("name"));
                allDirectory.setCall_detail(jsonArray.getJSONObject(i).getString("detail"));
                allDirectory.setProgress_indicator(0);
                catListDao.add(allDirectory);
            }
            catListDao1 = catListDao;
            adapter = new AdvisorsAdapter(act, R.layout.custom_equity, catListDao, 0);
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

}

public class FetchAllData extends AsyncTask<Void, Void, String> {
    ProgressDialog pDialog;
    int typeId;
    private Context cont;

    public FetchAllData(Context con, int typeId) {
        // TODO Auto-generated constructor stub
        this.cont = con;
        this.typeId = typeId;
        Log.d("Constructor Called", "yes");
    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        if (!swipeRefreshLayout.isRefreshing()) {
            if (progressBar != null) {
                progressBar.setVisibility(View.VISIBLE);
                set.start();
            }
        }
    }


    @Override
    protected String doInBackground(Void... params) {
        // TODO Auto-generated method stub
        return getString();
    }

    private String getString() {
        // TODO Auto-generated method stub

        URL obj = null;
        HttpURLConnection con = null;
        try {
            obj = new URL(Constants.AppBaseUrl + "/call_listing/" + typeId);
            String userPassword = "rickmams" + ":" + "advisor11";
            String header = "Basic " + new String(android.util.Base64.encode(userPassword.getBytes(), android.util.Base64.NO_WRAP));
            con = (HttpURLConnection) obj.openConnection();
            con.addRequestProperty("Authorization", header);
            con.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
            con.setRequestMethod("POST");

            // For POST only - BEGIN
            con.setDoOutput(true);
            OutputStream os = con.getOutputStream();

            os.flush();
            os.close();
            // For POST only - END

            int responseCode = con.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) { //success
                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                Log.i("TAG", response.toString());
                parseJSON(response.toString());
                return response.toString();

            } else {
                Log.i("TAG", "POST request did not work.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return null;
    }


    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        if (getActivity() == null)
            return;
        if (swipeRefreshLayout.isRefreshing()) {
            swipeRefreshLayout.setRefreshing(false);
        }
        if (result != null) {
            if (progressBar != null) {
                list.setAdapter(adapter);
                //pDialog.dismiss();
                if (progressBar != null) {
                    set.end();
                    if (progressBar.getVisibility() == View.VISIBLE)
                        progressBar.setVisibility(View.GONE);
                }
                if (jsonArray.length() != 0) {
                    empty_text.setVisibility(View.GONE);
                } else empty_text.setVisibility(View.VISIBLE);
            }
        }
    }


}

}

查看完整的堆栈跟踪,请访问http://pastebin.com/7FDynA05


如果您不使用执行器,而是让AsyncTask逐个运行,会怎样呢? - Randyka Yudhistira
这个操作需要很长时间,并且会导致ViewPager中的界面卡顿,这不是我想要的。 - Anshul Tyagi
你能否发布logcat的相关行以及代码中相关行(在logcat中出现的那些)? - Gavriel
Logcat已添加 @Gavriel - Anshul Tyagi
3个回答

2

我知道我来晚了,但是看到你有很多关于应用程序处理的问题,我没有发现任何错误,但还是想说,请检查一下是否每次都通过创建新对象来调用任何TypeFace,如果是,请将其注释掉并运行代码。


好的,等等让我来做。我也遇到了ListView滚动的问题。 - Anshul Tyagi

1

首先,我建议您使用任何网络库,可以是volley或retrofit。因为它们更有效率,而且它们会在后台并行处理调用,而不使用AsyncTask。

您正在尝试的方式最复杂,因为您正在同时调用。

如果需要,在恢复时才进行网络调用。其余内容可以在onCreateView中调用。或者您甚至可以选择在onStart中调用它。


@AnshulTyagi 你的volley实例是单例吗?如果不是,它会表现得相同并且执行每个调用并发,将其变为单例。 - UMESH0492
1
我强烈推荐使用Retrofit而不是Volley。你会有更多的自由。 - Jared Burrows
@AnshulTyagi,如果不需要,请勿在onResume中执行更多的工作。由于您使用了许多子片段,并且这些片段同时调用asynctask,因此会导致系统挂起线程以避免冻结。 - UMESH0492
在初始化所有UI组件后,您可以在onCreateView中调用它。 - UMESH0492
@UMESH0492 你好,我已经尝试过了,但是我的应用程序仍然会出现“暂停线程”的警告并关闭。 - Anshul Tyagi
显示剩余5条评论

0

不要在活动或片段中执行繁重的操作,否则每次修改用户界面时都必须处理问题(包括异步任务)。

您可以使用异步任务或像Volley这样的库,但要使用服务。一个好的教程在这里


你的意思是我需要使用后台服务来访问每个片段中的每个服务吗? - Anshul Tyagi
我的意思是最好将I/O和网络代码放在一个服务中,然后通过意图和消息从片段和活动处理它。这种方法将活动生命周期与网络操作分开。 - xcesco
您添加了一个链接,该链接说明了如何使用服务,而不是告诉我们如何通过使用单个“Service”类来管理不同片段的多个异步任务。 - Anshul Tyagi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接