因此,我在活动开始时启动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);
}
}
}
如果您需要更多详细信息,请提出要求。感谢。
答案 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);
}