#android #android-layout #bitmap
#Android #android-layout #растровое изображение
Вопрос:
У меня есть приложение в playstore, которое выдает следующую ошибку на очень немногих устройствах.
java.lang.IllegalArgumentException: width and height must be amp;> 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:829)
at android.graphics.Bitmap.createBitmap(Bitmap.java:808)
at android.graphics.Bitmap.createBitmap(Bitmap.java:775)
at com.my.app.fragments.ImageFragment$MyAsyncTask$1.void run()(SourceFile:209)
at android.os.Handler.handleCallback(Handler.java:745)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:5454)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
Ошибка возникает в этой строке в onPostExecute
в MyAsyncTask
c.drawBitmap(Bitmap.createBitmap(linearLayout.getWidth(), linearLayout.getHeight(), Bitmap.Config.RGB_565), 0, 0, p);
Это мой код
В моем ImageFragment
in onCreateView
я делаю это
ImageView img = (ImageView) rootView.findViewById(R.id.img);
final LinearLayout view= (LinearLayout) rootView.findViewById(R.id.view);
MyAsyncTask asyncTask= new MyAsyncTask(img, view);
asyncTask.execute(number);
Затем в AsyncTask
class MyAsyncTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private LinearLayout linearLayout;
public MyAsyncTask(ImageView imageView, LinearLayout linearLayout) {
imageViewReference = new WeakReference<>(imageView);
this.linearLayout = linearLayout;
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
// Code skipped
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
blurred = CommonUtils.fastblur(bitmap, 0.2f, 20);
final Bitmap resultBitmap = Bitmap.createBitmap(blurred.getWidth(), blurred.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(resultBitmap);
c.drawBitmap(blurred, 0, 0, null);
final Paint p = new Paint();
p.setAlpha(127);
linearLayout.post(new Runnable() {
@Override
public void run() {
c.drawBitmap(Bitmap.createBitmap(linearLayout.getWidth(), linearLayout.getHeight(), Bitmap.Config.RGB_565), 0, 0, p);
// Rest code skipped
}
});
}
}
}
}
После прочтения многих сообщений stackoverflow об этой проблеме я обнаружил, что это происходит, если представление еще не готово, и, следовательно, его следует использовать с методом post представления с вашим собственным runnable. Но я не могу понять, почему это все еще вызывает эту ошибку на некоторых устройствах, а именно Samsung
. У кого-нибудь есть идея, как это можно исправить? Любое предложение будет оценено. Спасибо!!
Ответ №1:
Ваша задача выполняется слишком быстро на этих устройствах, и LinearLayout
макет все еще не был выполнен. Вы можете использовать ViewTreeObserver
:
ViewTreeObserver vto = linearLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = linearLayout.getMeasuredWidth();
int height = linearLayout.getMeasuredHeight();
c.drawBitmap(Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565), 0, 0, p);
// Rest code skipped
}
});
Комментарии:
1. Спасибо за ответ. Я бы определенно попробовал это. Кстати, почему ViewTreeObserver должен работать?
2. Потому что вы пытаетесь получить размер макета до того, как макет был вычислен (т. Е. Вы все еще не знаете размеры, потому что Android все еще не вычислил их). ViewTreeObserver позволяет получать обратный вызов, когда это происходит: «View tree observer используется для регистрации прослушивателей, которые могут получать уведомления о глобальных изменениях в дереве просмотра. Такие глобальные события включают, но не ограничиваются, компоновкой всего дерева , началом прохода рисования, изменением режима касания …. » developer.android.com/reference/android/view /…
3. Кстати, я отредактировал ответ, чтобы исправить несколько ошибок в имени переменной.
4. Спасибо за ответ, попробую и приму его, если это сработает, большое спасибо!!