为什么我的doInBackground被召唤了这么多次?

时间:2015-03-21 11:41:19

标签: android android-listview android-asynctask navigation-drawer android-lifecycle

我有一个导航抽屉,onClick如下:

private class SlideMenuClickListener implements
    ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position,
                long id) {
            //  System.out.println("Clicked");
            mDrawerLayout.postDelayed(new Runnable() {
                @Override
                public void run() {
                    displayView(position);
                }
            }, 200);

        }
    }

我的displayView(位置);方法是:

private void displayView(int position) {
        // update the main content by replacing fragments
        Fragment fragment = null;
        switch (position) {
        case 0:

            fragment = new FragmentTab1();
            break;
        case 1:
            fragment = new FragmentTab2();
            break;
        case 2:
            fragment = new FragmentTab3();
            break;
        case 3:
            fragment = new FragmentTab3();
            //create dialog 



            break;
        default:
            break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
            .replace(R.id.frame_container, fragment).commit();

            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(navMenuTitles[position]);
            mDrawerLayout.closeDrawer(Gravity.LEFT);
        } else {
            // error in creating fragment
            Log.e("MainActivity", "Error in creating fragment");
        }
    }

现在在我的Fragment类的onCreateView中,我打电话给:

new ListLoader().execute(getActivity());

以下是实施:

public class ListLoader extends AsyncTask<Context, Void, CurAdapter> {

        ProgressDialog Asycdialog = new ProgressDialog(getActivity());
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub

            Asycdialog.setMessage("Working");
            Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL);
            Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
            Asycdialog.setCancelable(false);
            Asycdialog.show();
            super.onPreExecute();
        }

        protected void onPostExecute(CurAdapter result) {
            Asycdialog.cancel();
            lv.setAdapter(result);
        //  dbHelper.close();
        }

        @Override
        protected CurAdapter doInBackground(Context... params) {

            System.out.println("Loading list");
            dbHelper.open();
            final String status = fetch();
            Cursor mCur; 
            mCur = dbHelper.magicQuery(status); 
            Cur = new CurAdapter(getActivity(), mCur,0);    


            Cur.setFilterQueryProvider(new FilterQueryProvider() {
                public Cursor runQuery(CharSequence constraint) {
                    return dbHelper.getDirectoryList(constraint,status);
                }
            }); 


            return Cur;
        }


    }

每次打开和关闭导航抽屉时都会显示消息加载列表,是什么让它执行?我在我的onCreateView中放了一条System.out消息但是没有显示,而我只从onCreateView调用AsyncTask。我在这里想念什么?

即使我使用的是异步方法,我也会面临将NavDrawer项目点击到Fragment转换的闪烁。我不得不违背我的意愿使用加载进度对话框。

编辑:

罪魁祸首:

SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText){

            if (TextUtils.isEmpty(newText)){
                new ListLoader().execute(getActivity());
            }
            else {
                CursorAdapter filterAdapter = (CursorAdapter) Cur;
                filterAdapter.getFilter().filter(newText.toString());
            }

            return true;
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            return true;
        }
    };

编辑我摆弄了OnQueryTextListener并解决了这个问题。

    int ix =1; 
    SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText){
            if (TextUtils.isEmpty(newText)){
                if(ix == 2)
                    new ListLoader().execute(getActivity());


            }
            else {
                ix = 2;
                CursorAdapter filterAdapter = (CursorAdapter) Cur;
                filterAdapter.getFilter().filter(newText.toString());
            }

            return true;
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            return true;

        }
    };

1 个答案:

答案 0 :(得分:2)

原因:

FragmentNavigationDrawer一起使用时,这是观察到的行为。每次打开NavigationDrawer时,都会调用当前的Fragment onPause()onDestroy(),每次抽屉关闭时,当前{{1}调用了FragmentonCreateView()的{​​{1}}和onResume()

简而言之,Fragment被摧毁并在抽屉的每个打开/关闭循环中重新创建。这就是您重复调用AsyncTask的原因。

解决方案:

您有两种选择:

1。保存Fragment中每个onSavedInstanceState()的状态,并在onCreate()中恢复已保存的数据。仅当AsyncTasksavedInstanceStateonCreate()为空时才执行onCreateView()

2。尝试使用Activity代替Fragment s。打开/关闭抽屉时,不会重新创建Activity