Android Рисование Bitmap на Canvas
Нужно загрузить изображение по URL и отобразить отрисовать его в Canvas. Загрузка изображения в AsyncTask никак не меняет ситуацию. Делаю следующим образом:
class Lesson extends View {
public Lesson(Context context) {
super(context);
}
public InputStream downloadImageFromUrl() throws Exception {
URL url = new URL("https://mysite.ru/image.png");
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setDoInput(true);
httpsURLConnection.connect();
return httpsURLConnection.getInputStream();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
Bitmap bitmap = BitmapFactory.decodeStream(downloadImageFromUrl());
} catch (Exception e) {
e.printStackTrace();
}
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
Возникает ошибка: : Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference. Почему возникает эта ошибка и как можно её решить без использования SurfaceView?
Ответы (1 шт):
Автор решения: woesss
→ Ссылка
- Андроид запрещает выполнять сетевые операции в главном потоке. И собственно любые потенциально длительные операции выполнять в главном (он же UI) потоке - очень плохая практика. Это блокирует "отзывчивость" приложения, а то и всей системы. Поэтому подобные задачи следует выполнять в фоновых потоках (асинхронно). Сделать это можно множеством навороченных и не очень способов, в основе которых лежит класс потока
Thread. - метод
onDraw()является частью подготовки кадра и в нём делать что-то длительное и тем более каждый раз - тоже очень плохая идея. Нужно сократить логику этого метода до минимально необходимой для вывода кадра - в идеале, ничего кроме вызововcanvas.drawXXX()там быть не должно
Пример "на коленке", надеюсь поймёте принцип
class Lesson extends View {
// объявляем поле, в котором будем хранить ссылку на загруженный битмап
private Bitmap bitmap;
public Lesson(Context context) {
super(context);
// сразу при создании класса начинаем загрузку
new Thread(() -> {
try(InputStream stream = downloadImageFromUrl()) {
bitmap = BitmapFactory.decodeStream(stream);
if (bitmap == null) {
Log.e("Lesson", "что-то пошло не так");
} else {
// вызываем перерисовку
postInvalidate();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
public InputStream downloadImageFromUrl() throws Exception {
URL url = new URL("https://mysite.ru/image.png");
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setDoInput(true);
httpsURLConnection.connect();
return httpsURLConnection.getInputStream();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// проверяем есть ли картинка (возможно она ещё не загружена)
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
}