如何在列表项点击而不是 UI 线程上进行长时间操作?
How to make long operations on list item click but not on UI thread?
我有一个列表视图,其中每个项目包含 3 个按钮,一个用于保存在数据库中,另外两个用于打开新片段。我已经为适配器的 getView() 方法中的哪个按钮实现了 OnClickListener。当用户单击保存按钮时,我想在数据库中写入项目。既然,写入数据库被认为是一个长操作,不应该在UI线程上进行,请问如何进行?我应该创建自己的线程还是可以使用服务或异步任务?这是来自 getView 的代码:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
convertView=layoutInflater.inflate(R.layout.top_tracks_artists_item_layout,parent,false);
viewHolder=new ViewHolder();
viewHolder.trackName= (TextView) convertView.findViewById(R.id.top_tracks_item_name);
viewHolder.trackInfo= (Button) convertView.findViewById(R.id.top_tracks_item_info);
viewHolder.trackInfo.setTag(position);
viewHolder.trackInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "Info clicked " +position);
}
});
viewHolder.trackFavourite= (Button) convertView.findViewById(R.id.top_tracks_item_favourite);
viewHolder.trackFavourite.setTag(position);
viewHolder.trackFavourite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "favourites clicked " +position);
}
});
viewHolder.trackWatch= (Button) convertView.findViewById(R.id.top_tracks_item_watch);
viewHolder.trackWatch.setTag(position);
viewHolder.trackWatch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "Watch clicked " +position);
//here I want to save to database
}
});
convertView.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) convertView.getTag();
}
viewHolder.trackName.setText((String)tracks.get(position).toString());
return convertView;
}
提前致谢。
你可以试试AsyncTask,如果你想显示保存进度,也可以考虑在保存图像时显示一个旋转器。一旦你保存到数据库完成发送状态完成并关闭你的进度条。如果您需要一些关于如何操作的示例,请参阅下面 link。
对后台任务使用Android AsyncTask。用法是这样的;
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
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;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
您可以使用异步任务或处理程序来实现。在给定的 link
中查看以下教程和参考资料
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
服务
Not bounded to the Activity lifecycle , services will run even if your application is closed/switched/Config Changes
Operation to be performed by service Runs in the Main(UI) Thread,
So you need to create a Java-Thread inside onStartCommand() method
意向服务
Not bounded to the Activity lifecycle , services will run even if your application is closed/switched/Config Changes
Operation to be performed by IntentService runs in "single worker thread"
Note : Since it runs on "single worker thread" thus is not suited for Multithreaded Applications
AsyncTask
Bounded to Activity lifecycle , services will not run if your application is closed/switched/Config Changes,So you need to take these on consideration while using AsyncTask
我有一个列表视图,其中每个项目包含 3 个按钮,一个用于保存在数据库中,另外两个用于打开新片段。我已经为适配器的 getView() 方法中的哪个按钮实现了 OnClickListener。当用户单击保存按钮时,我想在数据库中写入项目。既然,写入数据库被认为是一个长操作,不应该在UI线程上进行,请问如何进行?我应该创建自己的线程还是可以使用服务或异步任务?这是来自 getView 的代码:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
convertView=layoutInflater.inflate(R.layout.top_tracks_artists_item_layout,parent,false);
viewHolder=new ViewHolder();
viewHolder.trackName= (TextView) convertView.findViewById(R.id.top_tracks_item_name);
viewHolder.trackInfo= (Button) convertView.findViewById(R.id.top_tracks_item_info);
viewHolder.trackInfo.setTag(position);
viewHolder.trackInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "Info clicked " +position);
}
});
viewHolder.trackFavourite= (Button) convertView.findViewById(R.id.top_tracks_item_favourite);
viewHolder.trackFavourite.setTag(position);
viewHolder.trackFavourite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "favourites clicked " +position);
}
});
viewHolder.trackWatch= (Button) convertView.findViewById(R.id.top_tracks_item_watch);
viewHolder.trackWatch.setTag(position);
viewHolder.trackWatch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("try", "Watch clicked " +position);
//here I want to save to database
}
});
convertView.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) convertView.getTag();
}
viewHolder.trackName.setText((String)tracks.get(position).toString());
return convertView;
}
提前致谢。
你可以试试AsyncTask,如果你想显示保存进度,也可以考虑在保存图像时显示一个旋转器。一旦你保存到数据库完成发送状态完成并关闭你的进度条。如果您需要一些关于如何操作的示例,请参阅下面 link。
对后台任务使用Android AsyncTask。用法是这样的;
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
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;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
您可以使用异步任务或处理程序来实现。在给定的 link
中查看以下教程和参考资料http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
服务
Not bounded to the Activity lifecycle , services will run even if your application is closed/switched/Config Changes
Operation to be performed by service Runs in the Main(UI) Thread, So you need to create a Java-Thread inside onStartCommand() method
意向服务
Not bounded to the Activity lifecycle , services will run even if your application is closed/switched/Config Changes
Operation to be performed by IntentService runs in "single worker thread" Note : Since it runs on "single worker thread" thus is not suited for Multithreaded Applications
AsyncTask
Bounded to Activity lifecycle , services will not run if your application is closed/switched/Config Changes,So you need to take these on consideration while using AsyncTask