Итак, я запускаю AsyncTask, когда начинается действие. Я пытаюсь реализовать бесконечный список. Когда пользователь прокручивает список до конца, 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);
        }
    }
}

Если вам нужна дополнительная информация, спросите об этом. Спасибо.

0
Chintan Soni 13 Авг 2014 в 14:47
2
Какую ошибку вы получаете? Всегда включайте logcat в вопрос, если возникают исключения.
 – 
Xaver Kapeller
13 Авг 2014 в 14:48
Конечно, сэр. Одну минуту.
 – 
Chintan Soni
13 Авг 2014 в 14:49
Извините, я не могу воспроизвести это. Потому что я пробовал с другим кодом. Но сейчас ситуация другая, задача не запускается.
 – 
Chintan Soni
13 Авг 2014 в 14:53
Я откатил ваше решение из самого вопроса. Вы можете найти его в истории изменений. Пожалуйста, опубликуйте его как ответ.
 – 
Cœur
29 Апр 2018 в 07:26

1 ответ

Лучший ответ

Проблема проста: вы можете выполнить каждый AsyncTask только один раз. Из документации AsyncTask :

Для этого класса необходимо соблюдать несколько правил потоковой передачи . чтобы работать правильно:

  • Класс AsyncTask должен быть загружен в поток пользовательского интерфейса. Это делается автоматически с JELLY_BEAN.
  • Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
  • 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);
}
1
Chintan Soni 13 Авг 2014 в 15:23
Спасибо, сэр. Пробую ... Сообщу, сработало ли.
 – 
Chintan Soni
13 Авг 2014 в 14:56
Выложил рабочее решение. Но я все еще не понимал, зачем нужен mCaseListingTask = new CaseListingTask();. Не могли бы вы объяснить это.
 – 
Chintan Soni
13 Авг 2014 в 15:16
Спасибо, сэр. Для вашего решения.
 – 
Chintan Soni
13 Авг 2014 в 15:17
В порядке. Японял твою точку зрения. Последний пункт Threading Rules, который вы упомянули. Еще раз спасибо.
 – 
Chintan Soni
13 Авг 2014 в 15:22