AsyncTask 图像压缩 - 致命例外:AsyncTask #3(稍后上传到 Firebase 存储))
AsyncTask Image Compression - FATAL EXCEPTION: AsyncTask #3 (Upload to Firebase Storage Later))
我正在尝试使用此 class ...
在后台线程中压缩图像
public class BackgroundImageResize extends AsyncTask<Uri, Integer, byte[]>{
Bitmap mBitmap;
public BackgroundImageResize(Bitmap bitmap) {
if(bitmap != null){
this.mBitmap = bitmap;
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(NextActivity.this, "compressing image", Toast.LENGTH_SHORT).show();
}
@Override
protected byte[] doInBackground(Uri... params) {
Log.d(TAG, "doInBackground: started.");
if(mBitmap == null){
try{
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
catch (NullPointerException e)
{
}
}
byte[] bytes = null;
bytes = getBytesFromBitmap(mBitmap, 100);
return bytes;
}
@Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
mUploadBytes = bytes;
//execute the upload task
}
}
public static byte[] getBytesFromBitmap(Bitmap bitmap, int quality){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality,stream);
return stream.toByteArray();
}
像
一样将位图传递给构造函数
BackgroundImageResize backgroundImageResize = new BackgroundImageResize(bitmap);
并在 onClickListener 中调用 execute() 方法,如
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: navigating to the final share screen.");
//Compress the image
backgroundImageResize.execute();
我收到了这个致命异常错误
4-27 00:10:01.318 17091-18093/manika.aditya.ekayana E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: manika.aditya.ekayana, PID: 17091
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at manika.aditya.ekayana.Share.NextActivity$BackgroundImageResize.doInBackground(NextActivity.java:158)
at manika.aditya.ekayana.Share.NextActivity$BackgroundImageResize.doInBackground(NextActivity.java:135)
at android.os.AsyncTask.call(AsyncTask.java:305)
每当我 运行 应用程序并单击 textView
我不明白是什么原因造成的...
稍后我必须将压缩后的图片上传到 Firebase Storage
这是上传方式,以防万一
public void uploadNewPhoto(String photoType, final String caption,final int count, final String imgUrl,
Bitmap bm){
Log.d(TAG, "uploadNewPhoto: attempting to uplaod new photo.");
FilePaths filePaths = new FilePaths();
//case1) new photo
if(photoType.equals(mContext.getString(R.string.new_photo))){
Log.d(TAG, "uploadNewPhoto: uploading NEW photo.");
String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
StorageReference storageReference = mStorageReference
.child(filePaths.FIREBASE_IMAGE_STORAGE + "/" + user_id + "/photo" + (count + 1));
//convert image url to bitmap
if(bm == null){
bm = ImageManager.getBitmap(imgUrl);
}
byte[] bytes = ImageManager.getBytesFromBitmap(bm, 90);
UploadTask uploadTask = null;
uploadTask = storageReference.putBytes(bytes);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri firebaseUrl = taskSnapshot.getDownloadUrl();
Toast.makeText(mContext, "photo upload success", Toast.LENGTH_SHORT).show();
//add the new photo to 'photos' node and 'user_photos' node
addPhotoToDatabase(caption, firebaseUrl.toString());
//navigate to the main feed so the user can see their photo
Intent intent = new Intent(mContext, HomeActivity.class);
mContext.startActivity(intent);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Photo upload failed.");
Toast.makeText(mContext, "Photo upload failed ", Toast.LENGTH_SHORT).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
if(progress - 15 > mPhotoUploadProgress){
Toast.makeText(mContext, "photo upload progress: " + String.format("%.0f", progress) + "%", Toast.LENGTH_SHORT).show();
mPhotoUploadProgress = progress;
}
Log.d(TAG, "onProgress: upload progress: " + progress + "% done");
}
});
我知道答案可能很明显,但我是初学者...提前谢谢您:)
我是这样调用上传方法的,顺便说一句
//upload the image to firebase
Toast.makeText(NextActivity.this, "Attempting to upload new photo", Toast.LENGTH_SHORT).show();
String caption = mCaption.getText().toString();
if(intent.hasExtra(getString(R.string.selected_image))){
imgUrl = intent.getStringExtra(getString(R.string.selected_image));
mFirebaseMethods.uploadNewPhoto(getString(R.string.new_photo), caption, imageCount, imgUrl,null);
}
else if(intent.hasExtra(getString(R.string.selected_bitmap))){
bitmap = (Bitmap) intent.getParcelableExtra(getString(R.string.selected_bitmap));
mFirebaseMethods.uploadNewPhoto(getString(R.string.new_photo), caption, imageCount, null,bitmap);
}
在 onClickViewListener 中
:P
根据您的日志,问题是
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
我相信,这是由 param[0]
行
引起的
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
params[]
必须是 null
,因为在 onClick()
中你调用 backgroundImageResize.execute()
时没有参数,它会被传递给 doInBackground()
并存储在 param[]
.
作为解决方案,您只需在 onClick()
中将 Uri 传递给 backgroundImageResize.execute()
,如下所示:
@Override
public void onClick(View v) {
...
backgroundImageResize.execute(myUri);
...
}
另一种方法 是通过在 doInBackground()
中捕获 ArrayIndexOutOfBoundsException
来避免您的应用程序崩溃,如下所示:
if(mBitmap == null){
try{
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
catch (NullPointerException e) {}
catch (ArrayIndexOutOfBoundsExeption aioobe) {}
}
我正在尝试使用此 class ...
在后台线程中压缩图像public class BackgroundImageResize extends AsyncTask<Uri, Integer, byte[]>{
Bitmap mBitmap;
public BackgroundImageResize(Bitmap bitmap) {
if(bitmap != null){
this.mBitmap = bitmap;
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(NextActivity.this, "compressing image", Toast.LENGTH_SHORT).show();
}
@Override
protected byte[] doInBackground(Uri... params) {
Log.d(TAG, "doInBackground: started.");
if(mBitmap == null){
try{
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
catch (NullPointerException e)
{
}
}
byte[] bytes = null;
bytes = getBytesFromBitmap(mBitmap, 100);
return bytes;
}
@Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
mUploadBytes = bytes;
//execute the upload task
}
}
public static byte[] getBytesFromBitmap(Bitmap bitmap, int quality){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality,stream);
return stream.toByteArray();
}
像
一样将位图传递给构造函数BackgroundImageResize backgroundImageResize = new BackgroundImageResize(bitmap);
并在 onClickListener 中调用 execute() 方法,如
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: navigating to the final share screen.");
//Compress the image
backgroundImageResize.execute();
我收到了这个致命异常错误
4-27 00:10:01.318 17091-18093/manika.aditya.ekayana E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: manika.aditya.ekayana, PID: 17091
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at manika.aditya.ekayana.Share.NextActivity$BackgroundImageResize.doInBackground(NextActivity.java:158)
at manika.aditya.ekayana.Share.NextActivity$BackgroundImageResize.doInBackground(NextActivity.java:135)
at android.os.AsyncTask.call(AsyncTask.java:305)
每当我 运行 应用程序并单击 textView 我不明白是什么原因造成的...
稍后我必须将压缩后的图片上传到 Firebase Storage
这是上传方式,以防万一
public void uploadNewPhoto(String photoType, final String caption,final int count, final String imgUrl,
Bitmap bm){
Log.d(TAG, "uploadNewPhoto: attempting to uplaod new photo.");
FilePaths filePaths = new FilePaths();
//case1) new photo
if(photoType.equals(mContext.getString(R.string.new_photo))){
Log.d(TAG, "uploadNewPhoto: uploading NEW photo.");
String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
StorageReference storageReference = mStorageReference
.child(filePaths.FIREBASE_IMAGE_STORAGE + "/" + user_id + "/photo" + (count + 1));
//convert image url to bitmap
if(bm == null){
bm = ImageManager.getBitmap(imgUrl);
}
byte[] bytes = ImageManager.getBytesFromBitmap(bm, 90);
UploadTask uploadTask = null;
uploadTask = storageReference.putBytes(bytes);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri firebaseUrl = taskSnapshot.getDownloadUrl();
Toast.makeText(mContext, "photo upload success", Toast.LENGTH_SHORT).show();
//add the new photo to 'photos' node and 'user_photos' node
addPhotoToDatabase(caption, firebaseUrl.toString());
//navigate to the main feed so the user can see their photo
Intent intent = new Intent(mContext, HomeActivity.class);
mContext.startActivity(intent);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Photo upload failed.");
Toast.makeText(mContext, "Photo upload failed ", Toast.LENGTH_SHORT).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
if(progress - 15 > mPhotoUploadProgress){
Toast.makeText(mContext, "photo upload progress: " + String.format("%.0f", progress) + "%", Toast.LENGTH_SHORT).show();
mPhotoUploadProgress = progress;
}
Log.d(TAG, "onProgress: upload progress: " + progress + "% done");
}
});
我知道答案可能很明显,但我是初学者...提前谢谢您:)
我是这样调用上传方法的,顺便说一句
//upload the image to firebase
Toast.makeText(NextActivity.this, "Attempting to upload new photo", Toast.LENGTH_SHORT).show();
String caption = mCaption.getText().toString();
if(intent.hasExtra(getString(R.string.selected_image))){
imgUrl = intent.getStringExtra(getString(R.string.selected_image));
mFirebaseMethods.uploadNewPhoto(getString(R.string.new_photo), caption, imageCount, imgUrl,null);
}
else if(intent.hasExtra(getString(R.string.selected_bitmap))){
bitmap = (Bitmap) intent.getParcelableExtra(getString(R.string.selected_bitmap));
mFirebaseMethods.uploadNewPhoto(getString(R.string.new_photo), caption, imageCount, null,bitmap);
}
在 onClickViewListener 中
:P
根据您的日志,问题是
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
我相信,这是由 param[0]
行
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
params[]
必须是 null
,因为在 onClick()
中你调用 backgroundImageResize.execute()
时没有参数,它会被传递给 doInBackground()
并存储在 param[]
.
作为解决方案,您只需在 onClick()
中将 Uri 传递给 backgroundImageResize.execute()
,如下所示:
@Override
public void onClick(View v) {
...
backgroundImageResize.execute(myUri);
...
}
另一种方法 是通过在 doInBackground()
中捕获 ArrayIndexOutOfBoundsException
来避免您的应用程序崩溃,如下所示:
if(mBitmap == null){
try{
mBitmap = MediaStore.Images.Media.getBitmap(NextActivity.this.getContentResolver(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
catch (NullPointerException e) {}
catch (ArrayIndexOutOfBoundsExeption aioobe) {}
}