2017-05-25 10 views
1

リストビューで画像と動画のサムネイルを読み込もうとしています。サムネイルを作成している間は、タスクを簡単に実行できるようにデフォルトのサムネイルを提供します。したがって、サムネイルのmakeとloadは別のスレッドに入れられます。しかし、問題は、アプリケーションのクラッシュ/終了です。スレッドをロード中にAndroidアプリケーションがクラッシュする

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

私が試してみました別のオプションは次のとおりです。

2つのスレッド、デフォルトの親指と上記T2と他の同じを提供する1つを作ります。 何も動作しません。

+0

例外ログはありますか? – litelite

+0

@ litelite ":android.view.ViewRootImpl $ CalledFromWrongThreadException:ビュー階層を作成した元のスレッドのみがビューに触れることができます。 –

+0

あなたのスレッドはビューを作成しなかったので、Androidはスレッドがビューに触れないようにしています。イメージをUIスレッドに戻す必要があり、そのスレッドでイメージを変更する必要があります。 ['AsyncTask'](https://developer.android.com/reference/android/os/AsyncTask.html)はそれに最適です。 – litelite

答えて

1

私はあなたがリストビューに、インターネットから画像をダウンロードするためである。この問題に見てください、このヘルプを願っています。しかし、それはあなたがやっていることに適応できるはずです。

リストビューに画像を入力するときは、さらに注意すべき点があります。 はい、AsyncTaskを使用してイメージをロードしますが、リストアイテムがサイト外に出て作業がまだ進行中のときに何が起こるかを考慮する必要もあります。 asyncTaskでweakreferencesを持つ回答を見て、必要がなくなったら操作を取り消してください。

また、todyaにはIonやのようなライブがあります。

Load asynchronous images in listView

0

UIスレッドで実行。 あなたが

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 
} 
} 
関連する問題