2017-05-25 5 views
1

Ich versuche, die Miniaturansichten von Bildern und Videos in der Listenansicht zu laden. Während ich ihre Thumbnails mache, stelle ich ein Standard-Thumbnail zur Verfügung, so dass die Aufgabe einfach erledigt werden kann und daher das Thumbnail make und and load in einen anderen Thread eingefügt wird. Aber das Problem ist, dass die Anwendung abstürzt/beendet wird.Android-Anwendung stürzt ab, während der Thread geladen wird

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; 
} 

eine weitere Option, die ich versucht habe ist:

machen zwei Threads, eine, die Standard Daumen liefern und andere gleiche wie t2 oben. Keine funktioniert.

+0

Haben Sie ein Ausnahmeprotokoll? – litelite

+0

@litelite ": android.view.ViewRootImpl $ CalledFromWrongThreadException: Nur der ursprüngliche Thread, der eine Ansichtshierarchie erstellt hat, kann seine Ansichten berühren." –

+0

Ihr Thread hat die Ansicht nicht erstellt. Daher verhindert Android, dass der Thread die Ansicht berührt. Sie müssen das Bild zum UI-Thread zurückholen und dann in diesem Thread das Bild ändern. ['AsyncTask'] (https://developer.android.com/reference/android/os/AsyncTask.html) ist dafür großartig. – litelite

Antwort

1

Ich schlage vor, Sie in dieser Frage suchen, die zum Herunterladen der Bilder aus dem Internet in Listviews ist. Aber es sollte auf das, was Sie tun, anwendbar sein.

Beim Auffüllen einer Listenansicht mit Bildern sind weitere Punkte zu beachten. Ja, Sie führen das Laden von Bildern mit einem AsyncTask, aber man muss auch considera was passiert, wenn das Listenelement aus der Website geht und die Arbeit ist noch im Gange. bei den Antworten suchen, die weakreferences im AsyncTask und den Vorgang abbrechen, wenn nicht mehr benötigt.

Auch Todya gibt es Libraties wie Ion oder Picasso, die es für Sie tun.

Load asynchronous images in listView

0

Auf UI-Thread ausführen. Hoffe diese Hilfe Sie

runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      //Your code to run in GUI thread here 
     }//public void run() { 
}); 
1
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 
} 
} 
Verwandte Themen