Android 加载线程时应用程序崩溃
Android Application crashes while loading the thread
我正在尝试在列表视图中加载图像和视频的缩略图。当我制作他们的缩略图时,我提供了一个默认缩略图,以便轻松完成任务,因此缩略图制作和加载被放在不同的线程中。但问题是应用crashes/exits。
public View getView(final int position, View convertView, ViewGroup parent)
{
File file=new File(String.valueOf(filenames[position]));
if(file.isDirectory()){
img=R.drawable.folder;
}
else{
img=getImage(filenames[position]);
}
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater inflator = LayoutInflater.from(getContext());
convertView = inflator.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) convertView.findViewById(R.id.textView1);
viewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
viewHolder.iv= (ImageView)convertView.findViewById(R.id.imageView);
viewHolder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int getPosition = (Integer) buttonView.getTag(); // Here we get the position that we have set for the checkbox using setTag.
myList.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
}
});
convertView.setTag(viewHolder);
convertView.setTag(R.id.textView1, viewHolder.tv);
convertView.setTag(R.id.checkBox1, viewHolder.cb);
convertView.setTag(R.id.checkBox1, viewHolder.iv);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.iv.getLayoutParams().height = 80;
viewHolder.iv.getLayoutParams().width = 80;
viewHolder.cb.setTag(position); // This line is important.
final ViewHolder finalViewHolder = viewHolder;
Thread t2 = new Thread(){
public void run(){
if((String.valueOf(filenames[position])).contains(".jpeg")||String.valueOf(filenames[position]).contains(".jpg")||String.valueOf(filenames[position]).contains(".png")||String.valueOf(filenames[position]).contains(".bmp")||String.valueOf(filenames[position]).contains(".webp")||String.valueOf(filenames[position]).contains(".gif")){
thumb = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(String.valueOf(filenames[position])), 64, 64);
finalViewHolder.iv.setImageBitmap(thumb);
}
else if((String.valueOf(filenames[position])).contains(".mp4")||String.valueOf(filenames[position]).contains(".mkv")||String.valueOf(filenames[position]).contains(".webm")||String.valueOf(filenames[position]).contains(".3gp")||String.valueOf(filenames[position]).contains(".3gpp")){
thumb=ThumbnailUtils.createVideoThumbnail(filenames[position].getPath(), MediaStore.Video.Thumbnails.MINI_KIND);
finalViewHolder.iv.setImageBitmap(thumb);
}
}
};
finalViewHolder.iv.setImageResource(img);
finalViewHolder.tv.setText(myList.get(position).getName());
finalViewHolder.cb.setChecked(myList.get(position).isSelected());
t2.start();
return convertView;
}
我尝试过的另一个选择是:
制作两个线程,一个提供默认拇指,另一个与上面的 t2 相同。
None 有效。
运行 在 UI 线程上。
希望这对你有帮助
runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
}//public void run() {
});
private class SomeTask extends AsyncTask<URL, Integer, Long> {
protected void doInBackground(String... str) {
//Do the background stuff here
}
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Long result) {
//Do the UI stuff here
}
}
我建议你研究一下这个问题,它是关于从互联网上下载图像到列表视图中的。但它应该适用于你正在做的事情。
用图像填充列表视图时需要注意更多事项。
是的,您 运行 使用 AsyncTask 加载图像,但您还必须考虑当列表项离开站点并且工作仍在进行时会发生什么。
查看 asyncTask 中有弱引用的答案,如果不再需要则取消操作。
此外,还有像 Ion or Picasso 这样的图书馆可以为您做这件事。
Load asynchronous images in listView
我正在尝试在列表视图中加载图像和视频的缩略图。当我制作他们的缩略图时,我提供了一个默认缩略图,以便轻松完成任务,因此缩略图制作和加载被放在不同的线程中。但问题是应用crashes/exits。
public View getView(final int position, View convertView, ViewGroup parent)
{
File file=new File(String.valueOf(filenames[position]));
if(file.isDirectory()){
img=R.drawable.folder;
}
else{
img=getImage(filenames[position]);
}
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater inflator = LayoutInflater.from(getContext());
convertView = inflator.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) convertView.findViewById(R.id.textView1);
viewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
viewHolder.iv= (ImageView)convertView.findViewById(R.id.imageView);
viewHolder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int getPosition = (Integer) buttonView.getTag(); // Here we get the position that we have set for the checkbox using setTag.
myList.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
}
});
convertView.setTag(viewHolder);
convertView.setTag(R.id.textView1, viewHolder.tv);
convertView.setTag(R.id.checkBox1, viewHolder.cb);
convertView.setTag(R.id.checkBox1, viewHolder.iv);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.iv.getLayoutParams().height = 80;
viewHolder.iv.getLayoutParams().width = 80;
viewHolder.cb.setTag(position); // This line is important.
final ViewHolder finalViewHolder = viewHolder;
Thread t2 = new Thread(){
public void run(){
if((String.valueOf(filenames[position])).contains(".jpeg")||String.valueOf(filenames[position]).contains(".jpg")||String.valueOf(filenames[position]).contains(".png")||String.valueOf(filenames[position]).contains(".bmp")||String.valueOf(filenames[position]).contains(".webp")||String.valueOf(filenames[position]).contains(".gif")){
thumb = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(String.valueOf(filenames[position])), 64, 64);
finalViewHolder.iv.setImageBitmap(thumb);
}
else if((String.valueOf(filenames[position])).contains(".mp4")||String.valueOf(filenames[position]).contains(".mkv")||String.valueOf(filenames[position]).contains(".webm")||String.valueOf(filenames[position]).contains(".3gp")||String.valueOf(filenames[position]).contains(".3gpp")){
thumb=ThumbnailUtils.createVideoThumbnail(filenames[position].getPath(), MediaStore.Video.Thumbnails.MINI_KIND);
finalViewHolder.iv.setImageBitmap(thumb);
}
}
};
finalViewHolder.iv.setImageResource(img);
finalViewHolder.tv.setText(myList.get(position).getName());
finalViewHolder.cb.setChecked(myList.get(position).isSelected());
t2.start();
return convertView;
}
我尝试过的另一个选择是:
制作两个线程,一个提供默认拇指,另一个与上面的 t2 相同。 None 有效。
运行 在 UI 线程上。 希望这对你有帮助
runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
}//public void run() {
});
private class SomeTask extends AsyncTask<URL, Integer, Long> {
protected void doInBackground(String... str) {
//Do the background stuff here
}
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Long result) {
//Do the UI stuff here
}
}
我建议你研究一下这个问题,它是关于从互联网上下载图像到列表视图中的。但它应该适用于你正在做的事情。
用图像填充列表视图时需要注意更多事项。 是的,您 运行 使用 AsyncTask 加载图像,但您还必须考虑当列表项离开站点并且工作仍在进行时会发生什么。 查看 asyncTask 中有弱引用的答案,如果不再需要则取消操作。
此外,还有像 Ion or Picasso 这样的图书馆可以为您做这件事。
Load asynchronous images in listView