私は理解度&知識がやや低いので他力本願である。
【 nyan のアプリ開発 [Android] 非同期処理 Executorの使い方 】
【 Android 11でdeprecatedになったAsyncTask対応Java編 】
2つの解説サイトを参考に
元[MyAsyncTask] を 代替え[MyAsyncTask2]クラスで置き換え。
不具合も無く、違和感も今のところ感じられない。
これで API 17以降使えるようになった。
今までの AsyncTask。
public class MyAsyncTask extends AsyncTask<String,Object,Object> {
private MainViewModel mViewModel;
private RecyclerView mRecyclerView;
private final int vID;
private final int saveSize;// 保存する画像サイズの目安
private int ret = 0;
public MyAsyncTask(MainViewModel data, RecyclerView rv, int id ) {
super();
mViewModel = data;
mRecyclerView = rv ;
vID = id;
saveSize = (int)mViewModel.getValueMyMainModel().getContext()
.getResources().getDimension( R.dimen.thumbnail_save_size );
}
// 別のスレッドで実行
@Override
protected Object doInBackground(String... p) { // MyTask.execute(引数);で呼ばれる
File souFile = new File(p[0]);
if ( !souFile.exists() || !souFile.isFile() ) return false;
File cacheDir = mViewModel.getValueMyMainModel().getCacheDir(souFile);
if ( cacheDir == null || ( !cacheDir.exists() && !cacheDir.mkdirs() ) ) return false;
File cacheFile = new File( cacheDir, souFile.getName() );
if ( cacheFile.exists() ) return true; // キャッシュファイルが無いからここに来ているけど..
ret = new MyMakeThumbnail().toThumbnailFile(souFile, cacheFile, saveSize);
return ret == 0;
}
// 終了後、メインスレッドで実行
@Override
protected void onPostExecute( Object result ) {
if ( result.equals(true) &&
mRecyclerView != null &&
mRecyclerView.getAdapter() != null &&
vID < mRecyclerView.getAdapter().getItemCount()
) {
boolean flag = false;
if (mViewModel.getValueRecyclerView_thumbnail() != null &&
mRecyclerView.getAdapter().equals(mViewModel.getValueRecyclerView_thumbnail().getAdapter())
)
flag = true;
else if (mViewModel.getValueRecyclerView_directory() != null &&
mRecyclerView.getAdapter().equals(mViewModel.getValueRecyclerView_directory().getAdapter())
)
flag = true;
if (flag)
mRecyclerView.getAdapter().notifyItemChanged(vID);
} else if (ret == -1)
// 省略
else if (ret == -2)
// 省略
mRecyclerView = null;
mViewModel = null;
}
}
代替え Executor を使ったワーカースレッド。
public class MyAsyncTask2 {
ExecutorService executorService;
private MainViewModel mViewModel;
private RecyclerView mRecyclerView;
private final int vID;
private final int saveSize;
private int ret = 0;
private String targetPath = "";
public MyAsyncTask2(MainViewModel data, RecyclerView rv, int id ) {
super();
executorService = Executors.newSingleThreadExecutor();
mViewModel = data;
mRecyclerView = rv ;
vID = id;
saveSize = (int)mViewModel.getValueMyMainModel().getContext()
.getResources().getDimension( R.dimen.thumbnail_save_size );
}
private class TaskRunnable implements Runnable {
@Override
public void run() {
File souFile = new File(targetPath);
if ( !souFile.exists() || !souFile.isFile() ) {
return;
}
File cacheDir = mViewModel.getValueMyMainModel().getCacheDir(souFile);
if ( cacheDir == null || ( !cacheDir.exists() && !cacheDir.mkdirs() ) ) {
return;
}
File cacheFile = new File( cacheDir, souFile.getName() );
if ( cacheFile.exists() ) return; // キャッシュファイルが無いからここに来ているけど..
ret = new MyMakeThumbnail().toThumbnailFile(souFile, cacheFile, saveSize);
new Handler(Looper.getMainLooper())
.post(() -> onPostExecute(ret == 0));
}
}
public void execute(String param) {
targetPath = param;
executorService.submit(new TaskRunnable());
}
void onPostExecute(boolean result) {
if ( result &&
mRecyclerView != null &&
mRecyclerView.getAdapter() != null &&
vID < mRecyclerView.getAdapter().getItemCount()
) {
boolean flag = false;
if (mViewModel.getValueRecyclerView_thumbnail() != null &&
mRecyclerView.getAdapter().equals(mViewModel.getValueRecyclerView_thumbnail().getAdapter())
)
flag = true;
else if (mViewModel.getValueRecyclerView_directory() != null &&
mRecyclerView.getAdapter().equals(mViewModel.getValueRecyclerView_directory().getAdapter())
)
flag = true;
if (flag)
mRecyclerView.getAdapter().notifyItemChanged(vID);
} else if (ret == -1)
// 省略
else if (ret == -2)
// 省略
mRecyclerView = null;
mViewModel = null;
}
}