Как стать автором
Поиск
Написать публикацию
Обновить

Пересмотрите старые проекты для Android 4.0

Время на прочтение3 мин
Количество просмотров13K
Сегодня, когда писал для своего сайта новый учебный пример, тренируясь на кошках, неожиданно столкнулся с одной проблемой на ровном месте. В коде программы нужно было реализовать загрузку изображения из интернета и сохранить его на SD-карточку. На первый взгляд задача не представляла трудностей, но проект вдруг стал выдавать ошибку.





Здесь надо сделать небольшое отступление. Я начал изучать программирование под Android сравнительно недавно и начинал с версии Android 2.3, так как у меня был телефон с такой же версией. И все проекты пробовал на эмуляторе под этой же версией. Пару месяцев назад для моего Samsung Galaxy SII вышло обновление до ICS (Android 4.0) и я стал создавать новые проекты под новую версию, а также переписывать свои учебные примеры под новую платформу. Периодически в Eclipse при загрузке старых проектов попадались строчки кода с зачёркнутыми методами. Было ясно, что данный метод устарел и нужно перечитать документацию.

В моём последнем случае ничего не подчёркивалось, а природа ошибки была не совсем ясна. В одном из моих уроков использовался схожий пример загрузки изображения из сети в ImageView, который прекрасно работал раньше в Android 2.3. Ради интереса, я запустил этот пример под эмулятором Android 4.0, будучи абсолютно уверенный в работоспособности примера. Но не тут-то было, и этот пример не запускался. Заменив в примере одну строчку

txtUrl.setText(e.toString());


я получил описание ошибки — android.os.NetworkOnMainThreadException. Дальше было проще. Имея эту информацию и призвал на помощь Гугл, я выяснил, что, начиная с Android 3.0 правила немного изменились. Теперь нельзя обращаться к сетевым ресурсам в основном потоке активности. Поэтому пришлось переделывать пример на новый лад.

Посмотреть код
package ru.alexanderklimov.imagefrominet;

import java.io.InputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

public class ImageFromInetActivity extends Activity {
	private ImageView imgView;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		imgView = (ImageView) findViewById(R.id.imgView);
		
		// Веб-адрес картинки
		String url = "http://developer.alexanderklimov.ru/android/images/android_cat.jpg";
		// show The Image
		new DownloadImageTask(imgView)
		.execute(url);
	}

	private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
		ImageView bmImage;

		public DownloadImageTask(ImageView bmImage) {
			this.bmImage = bmImage;
		}

		protected Bitmap doInBackground(String... urls) {
			String urldisplay = urls[0];
			Bitmap mIcon11 = null;
			try {
				InputStream in = new java.net.URL(urldisplay).openStream();
				mIcon11 = BitmapFactory.decodeStream(in);
			} catch (Exception e) {
				Log.e("Error", e.getMessage());
				e.printStackTrace();
			}
			return mIcon11;
		}

		protected void onPostExecute(Bitmap result) {
			bmImage.setImageBitmap(result);
		}
	}
}




В исправленном варианте пример заработал. Возможно, код ещё требует доработки, но уже ясно в каком направлении нужно двигаться.
Наверняка, компании и серьёзные разработчики в курсе этой проблемы. Решение проблемы уже описано и в документации и на StackOverflow.com. Профессионалы не пишут длительные операции в основном потоке и они и не заметят проблемы вообще. В моём случае для меня это стало сюрпризом, так как в рабочих проектах не было необходимости использовать загрузку изображений из интернета, а вот в учебном примере такой «неправильный» код попался. И думается, что для многих программистов-любителей это может стать головной болью. Представьте себе ситуацию, что в вашем приложении используется загрузка картинки или другого файла из интернета. И часть пользователей, которые обновились до ICS, начинает жаловаться, что ничего не работает. Другая часть пользователей с такой же моделью телефона будет утверждать, что всё прекрасно работает. Догадаться про источник проблемы будет достаточно затруднительно.

Вывод: Пересмотрите свои старые проекты на предмет работоспособности под Android 4.0. Буквально вчера обновилась статистика устройств под разные версии Android и Android 4 уже обогнала версию 2.1. Вполне допускаю, что к концу года четверка подвинет и версию 2.2. Поэтому нужно уже сейчас задуматься об этой проблеме.

P.S. Во время опытов при решении проблемы ни одно животное не пострадало.
Теги:
Хабы:
Всего голосов 63: ↑41 и ↓22+19
Комментарии29

Публикации

Ближайшие события