我有一个应用程序,用户可以从他们的图库中选择一张图片。
它会将图片放在ImageView
框中,并且有几个EditText
字段需要填写。
选择照片后,打开键盘需要几秒钟,显示文字输入等几秒钟。
我在AsyncTask
中进行所有图形操作等,如下所示:
调用AsyncTask:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK) {
try {
new SetPathAsync(data.getData()).execute();
}catch (Exception e){
Log.e("Error", "Error with setting the image. See stack trace.");
e.printStackTrace();
}
}
}
完成任务:
公共类SetPathAsync扩展了AsyncTask {
Uri uri;
// override this to set uri for bitmap
public SetPathAsync(Uri uriPass){
super();
uri = uriPass;
}
@Override
protected Boolean doInBackground(String... params) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
// Convert file path into bitmap image using below line.
bitmap = BitmapFactory.decodeFile(filePath);
filePathForUpload = filePath;
Log.i("Test", filePath);
try {
ExifInterface exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
bitmap = rotateBitmap(bitmap, orientation);
}catch (Exception e) {
Log.d("Error", "error with bitmap!");
e.printStackTrace();
}
return null;
}
public Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
button.setEnabled(false);
}
});
}
}
代码中的其他所有内容都只是普通的UI任务。
为什么在Async线程中仍然存在滞后的原因?
答案 0 :(得分:1)
不明显。你必须对它进行分析。
此外,无需在SetPathAsync构造函数中调用super(),也不需要runOnUiThread - onPostExecute已在UI线程上运行。
答案 1 :(得分:1)
这是因为位图的大小非常大,以至于应用程序完全没有内存,这意味着即使认为它是在新线程上完成的,仍然没有足够的内存来运行其他指令。
当我在logcat中遇到错误时,我注意到了这一点,例如:Grow heap (frag case)
。
为了解决这个问题,我按比例缩小了图像:
BitmapFactory.Options bmpOpts = new BitmapFactory.Options();
bmpOpts.inSampleSize = 3;
bitmap = BitmapFactory.decodeFile(filePath, bmpOpts);
现在它运行顺利!