我有一个带有许多不同ViewHolders的RecyclerView适配器 . 其中一个ViewHolders包含一个ImageView,它需要能够拍照,调整大小,然后显示它 . 对于模块化,我希望ViewHolder是自包含的:它而不是父活动应该处理有关照片拍摄和显示过程的所有内容 . 文件路径也是常量(它永远不会改变) . 实际上,它是 /storage/emulated/0/com.company.app/myst/cat.jpg
. 因此,这是我对ImageView的 onClick
方法的实现 .
@Override
public void onClick(View v) {
final FragmentManager fm = ((MyActivity) getContext()).getSupportFragmentManager();
Fragment auxiliary = new Fragment() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
resizeResaveAndDisplayPhoto();
super.onActivityResult(requestCode, resultCode, data);
fm.beginTransaction().remove(this).commit();
}
};
fm.beginTransaction().add(auxiliary, "FRAGMENT_TAG").commit();
fm.executePendingTransactions();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (null != takePictureIntent.resolveActivity(view.getContext().getPackageManager())) {
((MyActivity)view.getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
auxFragment.startActivityForResult(takePictureIntent, Constants.REQUEST_CODE_PHOTO);
}
}
当 resizeResaveAndDisplayPhoto
被调用时,它执行以下AsyncTask
public static class ResizeThenLoadImageTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewWeakReference;
private final WeakReference<File> fileWeakReference;
private final WeakReference<Context> weakContext;
private final int reqHeight;
private final int reqWidth;
public ResizeThenLoadImageTask(Context context, ImageView imageView, File file, int reqHeight, int reqWidth) {
weakContext = new WeakReference<Context>(context);
imageViewWeakReference = new WeakReference<>(imageView);
fileWeakReference = new WeakReference(file);
this.reqHeight = reqHeight;
this.reqWidth = reqWidth;
}
@Override
public Bitmap doInBackground(String... params) {
File file = fileWeakReference.get();
Bitmap bitmap = null;
if (null != file) {
bitmap = ImageUtils.reduceImageSize(file, reqHeight, reqWidth);
ImageUtils.saveBitmapToGivenFile(bitmap, file);
}
return bitmap;
}
@Override
public void onPostExecute(Bitmap bitmap) {
if (null != imageViewWeakReference && null != fileWeakReference) {
ImageView imageView = imageViewWeakReference.get();
File file = fileWeakReference.get();
if (null != imageView) {
if (null != bitmap) {
imageView.setImageBitmap(bitmap);
}
else {
imageView.setImageResource(R.drawable.photo);
}
imageView.postDelayed(new Runnable() {
@Override
public void run() {
if (null != weakContext.get()) {
((MyActivity) weakContext.get()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
}, 10000);
}
}
}
}
您可能会注意到我在拍照前锁定了方向,并在显示照片10秒后将其解锁 . 这个技巧是我的故障排除的一部分 . 所以情况就是这样 . 上述系统工作得很好 . 在下列情况下会出现问题
-
说我在ImageView中已经有了一张照片,但想要替换它 .
-
所以我点击ImageView拍摄一张新照片 .
-
如果我旋转设备拍摄新照片,那么当我返回新照片时,会在旧照片返回之前短暂显示 .
-
所以我锁定方向,看看发生了什么 . 这是我发现的 .
-
只要我锁定方向,就会显示新照片 . 一旦方向解锁(10秒),旧照片就会返回 .
-
如果我离开活动和返回,旧照片仍在显示 .
-
如果我完全关闭应用程序然后返回,那么我会看到新照片 .
1 回答
旋转设备时,会重新创建运行活动以及附加到其上的asyncTask,这可能会导致泄漏 .
您可能需要在活动中调用asyncTask而不是活动,因此asyncTask将附加到服务的生命周期 .