我正在创建一个Android应用,它具有搜索在线数据库的搜索功能。当我想要搜索某些内容时,我必须双击搜索按钮才能显示正确的结果。我相信问题在于我在按钮的onClick中使用了Asynctask函数。这是我的onClick:
public void onSearchClick(View view) throws TVDBOutboundConnectionException {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// fetch data
new SeriesSearchTask().execute(text.getText().toString());
} else {
// display error
}
final ListView listview = (ListView) findViewById(R.id.listview);
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < ALTS.size(); i++) {
list.add(ALTS.get(i).getSeriesName());
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
view.animate().setDuration(2000).alpha(0)
.withEndAction(new Runnable() {
@Override
public void run() {
list.remove(item);
adapter.notifyDataSetChanged();
view.setAlpha(1);
}
});
}
});
}
这是我的Asynctask方法:
private class SeriesSearchTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
ALTS = DB.searchSeriesInTVDB(urls[0], Language.ENGLISH);
return Integer.toString(ALTS.size());
} catch (TVDBOutboundConnectionException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
}
}
所以我的问题是如何让方法在一次搜索点击上显示正确的结果,因为这是正常的和预期的。感谢任何帮助,并提前感谢您的努力。
答案 0 :(得分:0)
您面临的问题是AsyncTask的工作原理。 AsyncTask中的代码在一个单独的线程上运行,因此之后的行会在AsyncTask完成工作之前立即执行 。
要在AsyncTask完成后更新UI,您需要在onPostExecute()
方法中执行代码。
然后将代码移到自己的方法中:
public void updateUi(){
final ListView listview = (ListView) findViewById(R.id.listview);
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < ALTS.size(); i++) {
list.add(ALTS.get(i).getSeriesName());
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
//...
}
然后将Activity切换到AsyncTask并在执行后在UI线程上运行此方法。
private class SeriesSearchTask extends AsyncTask<String, Void, String> {
MyActivity mActivity;
public SeriesSearchTask(final MyActivity _activity){
mActivity = _activity;
}
@Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
ALTS = DB.searchSeriesInTVDB(urls[0], Language.ENGLISH);
return Integer.toString(ALTS.size());
} catch (TVDBOutboundConnectionException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
//updating the UI here
if(mActivity != null){
mActivity.runOnUiThread(new Runnable(){
public void run(){
mActivity.updateUi();
}
}
}
}
}
更好的解决方案是使用像Otto之类的事件总线来通知活动。查看他们的网站,这是非常直接的。