在我的Android应用程序中,我想使用SwipeRefreshLayout刷新我的ListView,并且在onRefresh()方法中我想为此任务创建一个新线程。由于我的刷新方法必须获取一堆文件,它会在从主线程调用时暂时冻结应用程序,这会破坏使用SwipeRefrehLayout的全部目的(在应用程序刷新时通知用户,以及何时完成这样做。)
最后一部分是我遇到的麻烦。我想在获取文件后调用SwipeRefreshLayout.setRefreshing(false)来停止刷新anmimation。我这样做的方法是在新线程内的同一个刷新方法结束时调用setRefreshing,但问题是我得到一个错误说
Only the original thread that created a view hierarchy can touch its views.
我在想是否有创建线程结束监听器的方法,这是最好的方式,但遗憾的是我已经研究了几周而没有解决方案
每个人都使用SwipeRefreshLayout有明显的替代方案吗?任何帮助将不胜感激。
这里有一些代码,以防我的解释很糟糕(这是可以理解的)
public void onRefresh() {
// This method performs the actual data-refresh operation.
//I used refreshLayout.getContext() instead of the "this" keyword since "this" would return an OnRefreshListener instead of my actual context
//I pass my refreshLayout to the constructor so it knows which to stop animating at the end.
Thread thread = new Thread (new Refresher(refreshLayout.getContext(), refreshLayout));
thread.start();
//I use this to update the adapter in my ListView after it has been refreshed by my Refresher thread.
if (listView != null)
listView.setAdapter(new CategoryListAdapter(Categories, refreshLayout.getContext()));
}
我的复习课程: `
public class Refresher implements Runnable {
SwipeRefreshLayout refreshLayout;
Context context;
public Refresher (Context c, SwipeRefreshLayout rl) {
refreshLayout = rl;
context = c;
}
@Override
public void run() {
//Call the method that fetches the files.
((CategoryMenu) context).RefreshCategories(CategoryMenu.SaveDirectory);
//Here's where my error gets thrown.
refreshLayout.setRefreshing(false);
//I understand why, but I don't know a good workaround.
}
}
`
答案 0 :(得分:1)
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
refreshLayout.setRefreshing(false);
}
});
尝试使用runOnUiThread,希望这可以解决您的问题
答案 1 :(得分:0)
为了保持UI流畅,您可以使用AsyncTask,它将在后台执行操作,您可以获得进度更新并在任务完成时收到通知。 来自android dev site
的示例private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
// do some long running operation on the background
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
// pass the result to onPostExecute()
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
// update the UI when you're done
showDialog("Downloaded " + result + " bytes");
}
}