android:阻止另一个AsyncTask执行,如果一个已经在运行

时间:2014-08-13 10:47:25

标签: android listview android-listview android-asynctask

因此,我在活动开始时启动AsyncTask。我正在尝试实现无限列表视图。当用户滚动到listview的底部时,AsyncTask应该开始带来新数据。同时,如果用户向上滚动并再次向下滚动到底部,这就是我得到错误的地方。

以下是我尝试过的代码:

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class CaseListingActivity extends ActionBarActivity {

    ListView mListViewCase;
    ArrayList<CaseDetails> mArrayList;
    CaseListAdapter mCaseListAdapter;
    View mView;

    CaseListingTask mCaseListingTask;

    int preLast;
    int currentPage = 1;
    public static final String URL = "http://xxxxxx.xxxxxxx/DC.svc/rest/GetSubject?PageNo=";
    public static final String GET_SUBJECT_RESULT = "GetSubjectResult";
    public static final String ID = "Id";
    public static final String SUB = "Sub";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_case_listing);

        mArrayList = new ArrayList<CaseDetails>();
        mCaseListAdapter = new CaseListAdapter(this, mArrayList);

        mCaseListingTask = new CaseListingTask();

        mView = ((LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.listview_footer, null, false);

        mListViewCase = (ListView) findViewById(R.id.listViewCaseListing);
        mListViewCase.addFooterView(mView);
        mListViewCase.setAdapter(mCaseListAdapter);
        mListViewCase.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub
                // if (scrollState == SCROLL_STATE_IDLE) {
                // if (mListViewCase.getLastVisiblePosition() >= mListViewCase
                // .getCount() - 1 - 1) {
                //
                // // if (mCaseListingTask.getStatus() !=
                // AsyncTask.Status.RUNNING) {
                // //
                // // }
                // if (mCaseListingTask.getStatus() == AsyncTask.Status.RUNNING)
                // {
                // // Do Something?
                // } else {
                // currentPage++;
                // // load more list items:
                // mCaseListingTask.execute(URL + currentPage);
                // }
                // }
                // }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub
                switch (view.getId()) {
                case R.id.listViewCaseListing:

                    // Make your calculation stuff here. You have all your
                    // needed info from the parameters of this function.

                    // Sample calculation to determine if the last
                    // item is fully visible.
                    final int lastItem = firstVisibleItem + visibleItemCount;
                    if (lastItem == totalItemCount) {
//                      if (preLast != lastItem) { // to avoid multiple calls
//                          // for last item
//                          Log.d("Last", "Last");
//                          preLast = lastItem;

                            if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
                                currentPage++;
                                // load more list items:
                                mCaseListingTask.execute(URL + currentPage);
                            }
//                      }
                    }
                }
            }
        });
        mListViewCase.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                // TODO Auto-generated method stub
                Toast.makeText(getBaseContext(),
                        arg0.getItemAtPosition(arg2).toString(),
                        Toast.LENGTH_SHORT).show();
            }
        });

        new CaseListingTask().execute(URL + currentPage);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        getMenuInflater().inflate(R.menu.menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat
                .getActionView(searchItem);
        searchView.setOnQueryTextListener(new OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String arg0) {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean onQueryTextChange(String arg0) {
                // TODO Auto-generated method stub
                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

    public class CaseListingTask extends AsyncTask<String, Void, String> {

        ProgressDialog mProgressDialog;

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub

            String result = "";
            for (String string : params) {
                result = new JSONParser().getJSONFromUrl(string);
            }
            return result;
        }

        /*
         * (non-Javadoc)
         * 
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            try {
                JSONObject mJsonObject = new JSONObject(result);
                JSONArray mJsonArray = mJsonObject
                        .getJSONArray(GET_SUBJECT_RESULT);

                for (int i = 0; i < mJsonArray.length(); i++) {
                    JSONObject c = mJsonArray.getJSONObject(i);
                    mArrayList.add(new CaseDetails(c.getInt(ID), c
                            .getString(SUB)));
                }
                mCaseListAdapter.notifyDataSetChanged();

                mListViewCase.removeFooterView(mView);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /*
         * (non-Javadoc)
         * 
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            // mProgressDialog = ProgressDialog.show(CaseListingActivity.this,
            // "Please Wait...", "Loading...", true, false);

            mListViewCase.addFooterView(mView, null, false);
        }
    }
}

如果您需要更多详细信息,请提出要求。感谢。

1 个答案:

答案 0 :(得分:1)

问题很简单:您只能执行一次AsyncTask。来自the documentation of AsyncTask

  

此类必须遵循一些线程规则   正常工作:

     
      
  • 必须在UI线程上加载AsyncTask类。这是从JELLY_BEAN开始自动完成的。
  •   
  • 必须在UI线程上创建任务实例。
  •   必须在UI线程上调用
  • execute(Params ...)。
  •   
  • 不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。
  •   
  • 任务只能执行一次(如果尝试第二次执行则会抛出异常。)
  •   

您在CaseListingTask中创建onCreate()的新实例,并尝试在OnScrollListener中重复使用此相同的实例。您需要做的是每次要运行它时创建一个CaseListingTask的新实例。

总结一下,取而代之的是:

if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
    currentPage++;
    // load more list items:
    mCaseListingTask.execute(URL + currentPage);
}

有了这个:

if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
    currentPage++;
    mCaseListingTask = new CaseListingTask();
    mCaseListingTask.execute(URL + currentPage);
}