我应该在什么生命周期状态下在 Fragment 中执行异步任务?

In what lifecycle state should I execute an Async Task in Fragment?

加载片段时,我必须对远程服务器进行昂贵的调用。我使用默认的 Dashboard activity 和 NavigationView 来更改片段。但是,无论何时加载片段,它都会在执行包含 SOAP 请求代码的 AsyncTask 时冻结 UI 几秒钟。

我已经尝试从 onAttach()onStart() 执行 AsyncTask 但它仍然冻结 UI.

如何修复 UI 冻结?

编辑:- 异步任务代码:-

private class BindTreasuryTask extends AsyncTask<Void,Void,ArrayList<TreasuryData>> {

        private boolean NO_INTERNET;

        @Override
        protected ArrayList<TreasuryData> doInBackground(Void... voids) {
            try {
                // SOAP Call returns a JSONArray
                JSONArray jsonArray = apiHandler.performBindTreasury(payeeid);
                ArrayList<TreasuryData> td = new ArrayList<>();
                td.add(new TreasuryData("Select a treasury","none","none"));
                for(int i =0; i<jsonArray.size(); i++){
                    JSONObject j = (JSONObject) jsonArray.get(i);
                    td.add(new TreasuryData(j.get("TREASURY_NAME"),j.get("TREAS_CODE"),j.get("SCHEMA_NM")));
                }
                return td;
            } catch (IOException e) {
                NO_INTERNET = true;
                e.printStackTrace();
            } catch (XmlPullParserException | ParseException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(ArrayList<TreasuryData> treasuryData ) {
            if (treasuryData == null){
                if (NO_INTERNET){
                    Toast.makeText(getActivity(),"No Internet Connection",Toast.LENGTH_LONG).show();
                }
            } else {
                ArrayList<String> treasury = new ArrayList<>();
                for(int i=0;i<treasuryData.size();i++){
                    treasury.add(treasuryData.get(i).getTreasuryName());
                }
                setUpView();
            }
        }
    }

onActivityCreated() 可以是您的选择,昂贵的工作应该在 doInBackGround() 方法中完成。

正如 Ashok 回答的那样,您可以在 onActivityCreated() 方法中调用 AsyncTask。您可以使用线程或处理程序以 1-2 秒的延迟启动 SOAP 请求,这样可以避免在调用 Api 时冻结片段。或者,如果 UI 在您从导航抽屉切换片段时冻结,那么您可能必须管理自己的片段队列。