Опубликовано: журнал "Системный администратор" №11, 2013г.
Продолжаем изучать программирование для мобильных устройств на базе операционной системы от Google. Мы уже познакомились с инструментами Android SDK, попробовали создать свое первое приложение и запустили его в эмуляторе или на настоящем телефоне/планшете (см.[1], [2]). Наверняка кто-то захочет пойти дальше простого «Hello World!» на экране планшета и именно для них предназначена эта статья.
От командной строки к интегрированной среде разработки
Конечно, мы могли бы разработать наше следующее приложение исключительно с помощью текстового редактора, командной строки и Android SDK. Именно это и было сделано в [2]. Однако, сегодня я предлагаю читателю попробовать сделать приложение с помощью ADT (Android Developer Tools) - плагина для популярной среды разработки Eclipse. Этот плагин фактически интегрирует Android SDK в Eclipse делая рутинную работу программиста более изящной.
Плюсы работы в ADT мы уже указывали в [1] — это мощный редактор кода, интерактивная справка, мастера для создания проектов и классов, различные варианты представлений информации, компоновки. Добавим сюда наличие отладчика кода, возможность установки приложения на устройство/эмулятор прямо из Eclipse, отладки непосредственно на устройстве и станет ясно, что такими «благами цивилизации» стоит воспользоваться (см. также обзор возможностей [3]). Давайте создадим Android-проект в Eclipse с помощью ADT. В нем мы разберем для примера создание интерфейса приложения для Android с помощью ресурсных файлов а также рассмотрим применение в разработке так называемых «активов».
Установка связки ADT & Eclipse
Чтобы начать работать с ADT можно отдельно скачать плагин и установить его в Eclipse, однако инженерами Google рекомендуется использовать уже готовый вариант, который можно совершенно свободно взять из [4] - «Eclipse + ADT plugin» (другое название — «ADT Bundle»). Скачав архив для нужной операционной системы и установив, согласно инструкции, вы получаете готовую среду для наших опытов без лишних хлопот. Как установить ADT можно найти в Интернет, например в [5].
Краткое описание среды Eclipse
Установив и рассмотрев внимательно ADT разработчик, имеющий определенный опыт работы с другими IDE (интегрированными средами разработки), найдет в них много общего. Например, поработав с Delphi или Visual Basic можно легко «пересесть» на Eclipse практически без какой-либо подготовки. Однако, для тех кому покажется экран с установленной и запущенной IDE (см. рис.1) очень уж пугающим, расскажем немного о возможностях этой системы.
Рис.1 Окно с открытым проектом в IDE Eclipse
Для того чтобы разобраться с работой в Eclipse необходимо усвоить некоторые основные понятия, связанные с этой средой: рабочее пространство, инструменты, компоновки, редакторы и представления.
Рабочее пространство данной IDE связано с каталогом workspace, где лежат проекты и который обычно расположен в домашней директории пользователя /home/user/workspace или аналогичной в ОС Windows.
Инструментами (workbench) здесь считается почти все: сама платформа, главное меню, а также набор соответствующих редакторов и представлений, которые образуют компоновки (perspectives).
На рис. 1 изображено рабочее пространство Eclipse с открытой компоновкой Java, представлениями Package Explorer, Problems, LogCat и редактором кода Java. Думаю, такой вид окна Eclipse будет наиболее распространенным для Android-разработчика, а более углубленно данный материал можно изучить прочитав [6]). Скажем еще, что переключение между компоновками осуществляется с помощью меню Window->Open Perspective->Other.
Отметим, что плагин ADT относится к дополнениям (plug-ins) - так называют приложения, которые можно установить в Eclipse для расширения функционала.
В [2] мы подробно разбирали Android-проект, созданный с помощью SDK. Его структура ничем не отличается от собрата, который мы собираемся создать, так что знания уже полученные нами пригодятся для изучения сегодняшнего материала.
Для создания проекта в ADT достаточно воспользоваться соответствующим пунктом меню File->New->Android Application Project. При этом запускается мастер создания проектов. Однако прежде чем мы сделаем это хотелось бы кратко рассказать о том, чем мы будем заниматься и какова цель создания нашего приложения.
Еще о ресурсах
Для построения графического интерфейса пользователя в ОС Android, как мы уже разбирали, используются элементы, которые описываются в обычных текстовых файлах, имеющих структуру расширяемого языка разметки XML (так называемых «ресурсах»).
Такие файлы можно поместить в подкаталоге res/ — тогда при сборке проекта они будут «скомпилированы в двоичный формат» при помощи специального инструмента AAPT (Android Asset Packaging Tool). При этом появляется возможность обращаться к ним в Java-коде через так называемые «идентификаторы ресурсов» с помощью вспомогательного класса R. Вспомните строку
setContentView( R.layout.main );
нашего первого Android-проекта.
Кроме ресурсных файлов из res/, мы рассмотрим содержимое еще одного интересного каталога - assets/. В нем, по задумке создателей SDK, можно хранить произвольные необрабатываемые AAPT файлы (их еще называют «активами»). Путь к такому файлу является относительным и начинается с assets/. Для доступа к содержимому активов в SDK существует специальный Java-класс AssetManager.
Для более глубокого изучения различных вариантов использования ресурсов можно обратиться сюда.
Поставим себе цель — написать приложение для Android, которое будет выводить список, соответствующий содержимому подкаталога из assets/. При выборе какого-либо пункта из списка приложение прочитает необходимый файл.
Наш проект будет, конечно же, тестовым, но в такой структуре скрыта идея реальной программы, где в текстовых файлах хранится «статическая» информация (такой подход имеет смысл, когда некоторые данные, используемые приложением, почти не изменяются).
Создание проекта
Итак, с помощью меню File->New->Android Application Project создадим новый проект с именем AssetsFileLister (см. рис. 2). Нам необходимо также указать мастеру, где будут располагаться файлы проекта, создавать ли иконку для проекта, указать имя для будущей Activity и его вид (хотя можно все эти параметры оставить по умолчанию — так и было сделано автором).
Замечание: некоторые параметры, указанные нами мастеру (а именно имя пакета - Package name), "не понравились" Eclipse. Для привлечения внимания пользователю напротив этого параметра показан восклицательный знак в треугольнике. Дело здесь в имени пакета. Подробную информацию о пакетах см. здесь. Использовать имя пакета com.example.* можно только для пробных программ и тестовых проектов.
Рис.2 Окно мастера создания нового проекта
После завершения работы мастера познакомьтесь с представлением Package Explorer в левой части окна Eclipse. Найдите, например, уже знакомый нам AndroidManifest.xml. Двойной клик откроет этот файл в редакторе, в центре окна. Причем, можно выбрать вид просмотра параметров нашего приложения в закладках внизу редактора — или просто просмотреть его в текстовом виде с удобной синтаксической подсветкой.
Посмотрим также на размещение элементов Activity, описанное в нашем случае, в /res/layout/activity_main.xml. Здесь, кроме просмотра этого файла в текстовом редакторе, есть возможность размещать элементы интерфейса с помощью технологии Drag'n'Drop, переключившись на закладку GraficalLayout, внизу окна редактора.
Теперь мы в общих чертах рассмотрели основные приемы работы в ADT. Далее я буду заострять ваше внимание лишь на том, где и в каком файле потребуется написать необходимый код, останавливаясь на самых интересных местах проекта и некоторых концепциях разработки в ОС Android. Весь проект целиком можно скачать здесь.
//TODO
Как было сказано выше, в Eclipse есть вещи, которые делают работу программиста более продуктивной. Например, комментарий //TODO (а именно с двойного слеша начинаются комментарии в Java-коде) позволяет вставить напоминание о том, что нужно сделать еще в программе, выделяя это место синтаксической подсветкой и значком на полях, подобному напоминанию об ошибке.
Итак, в /res/values/strings.xml необходимо описать название приложения и название кнопки для выбора файла из списка
Далее, нужно описать элементы интерфейса нашего приложения в /res/layout/activity_main.xml
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list_of_files"
/>
Как видно из файла ресурсов, на экране нашего приложения будет кнопка (Button) и список (ListView). Остановимся подробнее на последнем элементе. Судя по названию ListView — это просмотр некоторой информации в виде списка. Если обратиться к документации из developer.android.com, то можно найти более замысловатое определение. Там уже используются такие концептуальные понятия Android-разработки как View, ViewGroup и Adapter (см. врезку). Итак, ListView — это группа видов (ViewGroup), которая показывает список прокручиваемых (scrollable) пунктов. Список пунктов автоматически заполняется при помощи адаптера, который предоставляет содержимое из источника — массива или запроса к базе данных.
Обратим внимание, что весь код по созданию интерфейса пользователя сосредоточен в ресурсных файлах (о возможных вариантах кодирования интерфейса см. [7] с.154).
Теперь, для воплощения нашей идеи в жизнь, создадим структуру файлов и каталогов в директории /assets нашего проекта. Средствами операционной системы создадим там подкаталог group1 и в нем файлы file1.txt, file2.txt, file3.txt, file4.txt, file5.txt. Для того чтобы информация о сделанных изменениях появилась в Eclipse нужно в представлении Package Explorer в нашем проекте выбрать «assets» и нажать клавишу F5.
Нам нужно создать еще один файл в каталоге res/xml/. Чтобы сделать это прямо в Eclipse необходимо нажать правую кнопку в представлении Package Explorer и в открывшемся меню выбрать New, а затем Folder или File. Давайте создадим файл /res/xml/namelist.xml и запишем в нем соответствие русских названий пунктов ListView файлам в поддиректории assets/group1/:
Далее, нам придется внести изменения в файл с описанием нашего явления (Activity), а точнее - MainActivity.java. Чтобы заработала наша кнопка, необходимо в первой строке описания нашего класса
public class MainActivity extends Activity {
дописатьimplements OnClickListener
и добавить пустой код обработчика нажатия кнопки в класс MainActivitypublic void onClick(View arg0) { }
Его мы заполним позже, после некоторых разъяснений.
Затем добавим в наш класс переменные
Отметим, что при объявлении экземпляра какого-либо класса в Java, необходимо подключить нужные модули в секцию import java-файла. Для автоматизации добавления нужного импорта воспользуйтесь комбинацией кнопок Ctrl+Shift+o.
Здесь нужно упомянуть об одном из инструментов отладки Android-приложений — logcat. Он отображает сообщения логов, рассылаемые при помощи класса android.util.Log, программные исключения и другую информацию. Написать самому сообщение в лог можно, например, с помощью такой команды
Log.d(LOG_TAG, "Сообщение 1");
где LOG_TAG — объявленная нами строковая переменная с именем лога (имя нужно для фильтрации сообщений, см. об этом ниже).
Далее, в нашем классе MainActivity, создадим функцию, которая читает информацию из namelist.xml и заполняет парами значений «русское название» - «название файла» java-контейнер Map. Здесь показан еще один прием работы с ресурсами Android (парсинг XML-файла):
Resources res = this.getResources();
XmlResourceParser xp = res.getXml(R.xml.namelist);
String filename = "";
xp.next();
int eventType = xp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
if (eventType == XmlPullParser.START_DOCUMENT)
{
Log.d(LOG_TAG, "StartReadXMLDocument");
}
else if (eventType == XmlPullParser.START_TAG)
{
if (!xp.getName().equals("namelist"))
{
filename = xp.getName();
}
}
else if (eventType ==XmlPullParser.TEXT)
{
fMap.put(xp.getText(), filename);
}
eventType = xp.next();
}
}
Мы совсем недалеко от цели — создадим описанный в /res/layout/activity_main.xml интерфейс приложения, используя обработчик события onCreate() нашего Activity:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//берем информацию из xml-файла в контейнер Map
try {
getFileTableFromXML();
}
catch (IOException ioe) {}
catch (XmlPullParserException xmlppe) {}
//преобразуем значения ключей Мар в массив названий
Set<String> ks = fMap.keySet();
files = new String[ks.size()];
files = ks.toArray(files);
//Создаем список
fileListView = (ListView) findViewById(R.id.list_of_files);
// устанавливаем режим выбора пунктов списка
fileListView.setChoiceMode (AbsListView.CHOICE_MODE_SINGLE);
//создаем адаптер
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, files);
//адаптер передает значения массива списку
fileListView.setAdapter(adapter);
//рисуем кнопку и устанавливаем ее обработчик
Button btnChecked = (Button) findViewById(R.id.btnChecked);
btnChecked.setOnClickListener(this);
}
Здесь мы создаем ListView с одиночным выбором пункта списка (CHOICE_MODE_SINGLE) и передаем ему массив русских названий файлов files через адаптер (ArrayAdapter).
Установим также обработчик для нашей кнопки.
//читаем данные из файла
String fname = fMap.get(files[fileListView.getCheckedItemPosition()]);
try {
//из TreeMap берем имя файла и читаем из него
InputStream is = getAssets().open("group1/" + fname);
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
//обнуляем ArrayList
l.removeAll(l);
while ( !(inputLine = in.readLine()).equals("@->endofpmfile<-@") ) {
Log.d (LOG_TAG, inputLine);
}
in.close();
} catch (IOException ioe) {}
}
В этом коде мы берем название из выделенного пункта ListView, ищем по нему название файла, затем с помощью getAssets получаем к нему доступ и читаем строки, записывая их в logcat.
Что же теперь? Наш проект вступает в заключительную фазу — сборка и установка приложения на эмулятор или реальное устройство. Итак, подключите устройство с Android к компьютеру при помощи USB или подготовьте к работе эмулятор (см. [1]). Включите на устройстве отладку по USB (Настройки->Для разработчиков->Отладка по USB). Откройте в редакторе Eclipse файл с описанием Activity — MainActivirty.java. Выберите пункт меню Run->Run (или нажмите сочетание клавиш Ctrl->F11). Программа через некоторое время должна запуститься на устройстве/эмуляторе (см. рис 3). Для просмотра логов, а именно туда будут выдаваться сообщения программы, необходимо в представлении LogCat добавить фильтр «MyLogs» (поищите плюсик в LogCat).
рис.3 device.jpg Экран планшета с запущенным приложением AssetsFileListerApp
Несколько слов для желающих повозиться с отладчиком Eclipse. Поскольку наше приложение использует logcat для вывода сообщений, то использовать отладчик как будто не зачем. Однако в реальных программах этот инструмент просто незаменим. В любой точке программы вы можете поставить точку прерывания (breakpoint) в левой части редактора (серой полосе разделяющей представление Package Explorer и редактор) двойным кликом мыши. Затем, при тех же условиях (подключено устройство, выбран файл с Activity в редакторе), нажатие клавиши F11 (или выбор Run->Debug в меню) приводит к открытию перспективы Debug в Eclipse, с возможностью пошаговой отладки вашего приложения прямо на устройстве с помощью клавиши F6.
Итак, в этой и предыдущих статях (см.[1], [2]), показаны основные принципы работы в Android SDK и ADT, а также инструменты и технологии, какими пользуются программисты при создании приложений для Android. В заключении хочется сказать, что многие опытные разработчики отмечают, что лучший способ научиться программировать и изучить возможности какой-либо IDE или платформы (фреймворка) - это самостоятельно попытаться создать какой-либо проект. В остальном, для желающих разобраться в перипетиях Android-разработки с помощью SDK и ADT, можно порекомендовать различный материал в сети. Я, например, с удовольствием смотрю видео-уроки и изучаю материалы в [5]. А из литературы неплохим выбором для дальнейшего изучения будет [7], [8]. Желаю вам успехов в изучении самой популярной в мире мобильной платформы - Android!