前回の複数の作業ディレクトリの切り替え利用は、整合性に問題が出て、解決も難しいので今後の課題とした。
色々と考える中でRecyclerViewのAdapterの中で、キャッシュ確保とスレッドスタートでも問題なく動くのか?
試しにやってみようと組んでみた。
アダプタ用のリストを受け取った時にリストと作業用ディレクトリをスレッドへ渡してスタート。
スレッド内で作業用ディレクトリをクリア、リストの画像ファイルをサムネイル画像にして作業用ディレクトリへ保存。
複数ディレクトリの時の例外ストップも出ず、いい感じで動いている。
実機テストで良い結果(速度)が出るといいけど、ディレクトリ移動モードのキャッシュ部分を組み込んでからのお楽しみ。
先ず、アダプタから。部分省略。
public class MyThumbnailAdapter extends RecyclerView.Adapter< MyThumbnailAdapter.ViewHolder> {
private Context myContext = null;
private List< String> myImageAbsPaths = null;
private File myCacheDir = null;
private MyThumbnailRunnable myThumbnailRunnable = null;
public MyThumbnailAdapter( Context context ) {
myContext = context;
myInflater = LayoutInflater.from( context );
myImageAbsPaths = new ArrayList<>();
setTempBufferDir( new File( context.getCacheDir(), "tempThumb" ) );
}
// 省略 //
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if ( myImageAbsPaths == null ) return;
File file = new File( myImageAbsPaths.get(position) );
Bitmap bitmap = loadImage( file );
if (bitmap != null)
holder.imageView.setImageBitmap(bitmap);
else
holder.imageView.setImageBitmap( BitmapFactory.decodeResource( myContext.getResources(), R.drawable.not_find) );
holder.textView.setText( String.valueOf( position + 1 ) );
holder.linearLayout.setId( holder.getAdapterPosition() );
holder.linearLayout.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
myListener.onClick(v);
}
});
}
public Bitmap loadImage( File file ) {
if ( file == null || !file.exists() || !file.isFile() ) return null;
File cf = new File( myCacheDir, file.getName() );
Bitmap scaleBitmap = null;
if ( cf.exists() ) {
scaleBitmap = BitmapFactory.decodeFile(cf.getAbsolutePath());
} else {
// 省略 //
}
return scaleBitmap;
}
public void addAll( List< String> imageAbsPaths ) {
myImageAbsPaths.clear();
myImageAbsPaths.addAll( imageAbsPaths );
myThumbnailRunnable = new MyThumbnailRunnable( myImageAbsPaths, myCacheDir );
new Thread( myThumbnailRunnable ).start();
notifyDataSetChanged();
}
public void setTempBufferDir( File dir ) {
if ( !dir.exists() && !dir.mkdirs() ) return;
myCacheDir = dir;
}
// 省略 //
}
スレッド用のRunnable。
public class MyThumbnailRunnable implements Runnable {
private List< String> mFileAbsPathList = null;
private File mCacheDir = null;
MyThumbnailRunnable( List< String> absList, File cachedir ) {
mFileAbsPathList = new ArrayList<>( absList );
mCacheDir = cachedir;
}
@Override
public void run() {
if ( mCacheDir == null || mFileAbsPathList.size() == 0 ) {
finish();
return;
}
clearBuffer();
createThumbnail();
finish();
}
private void clearBuffer() {
File[] files = mCacheDir.listFiles();
if ( files != null && files.length != 0 ) {
boolean b;
for ( File file: files ) {
b = file.delete();
}
}
}
private void createThumbnail() {
File cfile, souFile;
for ( int i = 0; i < mFileAbsPathList.size(); i++ ) {
souFile = new File( mFileAbsPathList.get(i) );
cfile = new File( mCacheDir, souFile.getName() );
if ( !cfile.exists() )
bitmapToThumbnaile( souFile, cfile );
}
}
// 省略 //
}
バッファ利用でバッファ処理が重ならないのでフラグが省ける。
画像の枚数が少なければ処理時間も短い。
ディレクトリ移動モードはどうだろう・・。