Основы Android-приложения

Android — основанная на linux платформа для мобильных устройств использующая изменённую виртуальную машину Java построенную для учёта компактности файлов и энергоэффективности Dalvik. Из-за этого используется не Mobile Edition и тем более не Java SE, а свои библиотеки.

Приложения соответсвенно пишутся на Java, либо же через обходные пути  — TitaniumAppInventorAdobe AIR. Интересно что из библиотек есть SQLite и OpenGL — не прийдётся изобретать велосипеды. Кроме того в системе есть менеджеры для обмена данными между приложениями, сенсорами и тп.

Многозадачность системы реализуется на программном уровне. Если в ПК приложения постоянно висят в оперативной памяти, а процессор прыгает между ними, то здесь каждое приложение это экземпляр класса Activity который может быть в разных состояниях

Обучающий материал для андроида пишется в двух разных мирах — для игр и для приложений.

Я рассматриваю именно приложения.   Итак — скачиваем и устанавливаем JRE, JDK, SDK, Eclipse + plugin и открываем новый Android-проект. Я думаю до этого вы сами дойдёте. Типичное приложение может  состоять из 4 основных мега-блоков — Activity, Intent Receiver, Service, Content Provider которые описываются в AndroidManifest.xml, вместе с запрашиваемыми привилегиями.

Делаем страницу (Activity)

Страница делается просто наследованием Activity класса и использовании менеджера ресурсов указывающем на внешний вид

public class MyKillerActivity extends Activity { //моя убийственная страничка
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        //использует шаблон main.xml через менеджер ресурсов
    }
}

Продумываем внешний вид (View)

Шаблоны отвечающие за внешний вид как и прочие данные лежат в XML-формате в /res папке. Локализация под другие страны и языки делается визардом который просто добавляет префиксы к файлам или папкам.

  • layout/*.xml — собственно шаблоны UI элементы со всякими кнопочками и текстовыми полями
  • values/strings.xml где лежат переводы для текстов UI
  • colors.xml, menu.xml, settings.xml

Для размеров и местоположения элементов используются разрывающие мозг единицы — px, pt, dip, sp.. Для дебага есть Hierarchy Viewer. В отличие от умного HTML в андроиде  позиционирование элементов задаётся структурными элементами

  • LinearLayout — дети ставятся друг за другом внутри родителя в заданном направлении. Если задан weight, то свободное место родителя перераспределяется между детьми
  • RelativeLayout — дети ставятся относительно родителя или ранее поставленного элемента
  • FrameLayout — дети ставятся сверху слева относительно и поверх родителя
  • TableLayout — аналог HTML-таблиц но без объединения ячеек
  • AbsoluteLayout — устарел из-за разных размеров устройств

Наполняем данными (Adapters)

Адаптеры нужны для показа динамического содержания на наследующих ListActivity страницах, которые могут содержать контейнер элементов — вертикальный список (ListView), таблицу (GridView), галерею (Gallery), выпадающий список (Spinner) или сгруппированный список (ExpandableListView). Адаптеры же передают данные из массивов/БД/интернета в шаблон. Связывается адаптер вызовом метода..

setListAdapter(new ArrayAdapter(this,
    android.R.layout.simple_list_item_1,    //встроенный шаблон для каждого ряда
    new String[]{"item 1", "item 2"}        //собственно данные
));

Есть много готовых адаптеров — ListAdapter, SimpleAdapterArrayAdaptor, CursorAdapter, SimpleCursorAdapter… и всегда можно написать свой, унаследовав абстрактный BaseAdapter.

При наполнении данными могут понадобится всякие фичи. Например форматирование дат зависит от настроек пользователя..

Calendar c = Calendar.getInstance();
c.setTimeInMillis(1000*json_row.getLong("timestamp")); //конвертируем int-timestamp полученный из mysql по json. Из секунд в миллисекунды
android.text.format.DateFormat.getTimeFormat(getApplicationContext()).format(date_added); //время вида 12:10AM
android.text.format.DateFormat.getDateFormat(getApplicationContext()).format(date_added); //дата вида 5/12/2010

Или например если вы хотите ссылки в своём TextView, то HTML частично преобразовывается с помощью Html.fromHtml() метода и android:autoLink=»web» параметра у элемента. А если надо вручную у «X ребёнка» что-то сделать то есть getChildAt метод. 

Добавляем ссылки (Intent)

С помощью Intent пользователя можно переносить на другую страницу, в телефонную книжку, браузер и тп. При этом текущая Activity приостанавливается и в неё можно будет вернуться back-кнопкой.  В передаваемую activity можно передавать дополнительные данные не только в формате key-value но и используя Bundle объект. Вот как это выглядит..

startActivity(new Intent(MyKillerActivity.this, MyWeakMinionActivity.class)); //перейдёт к другой странице по именам классов
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://kurapov.name"))); // открыть сайт в браузере
Intent search = new Intent(Intent.ACTION_WEB_SEARCH);  //браузерный поиск
search.putExtra(SearchManager.QUERY, "куплю снег");
startActivity(search);

Ещё один мощный тип управления это меню (Submenu) выскакивающее при нажатии одноимённой кнопки устройства. Ещё есть его расширение (вертикальный список) и контекстные меню при долгом нажатии на View-элемент, но сейчас не об этом. Меню добавляется как xml файл и прикрепляется к Activity как метод onCreateOptionsMenu, а для обработки нажатия используется onOptionsItemSelected метод, куда и нужно вставлять Intent в зависимости от выбранного элемента.

Подгружаем данные (AsyncTask)

К этому моменту у нас есть шаблон, есть возможность передачи данных в него и даже переходы между страницами, но нет самой основы — подгрузки данных из интернета или БД. Первое надо при простейшей небезопасной авторизации.. Долгие процессы надо выделять в асинхронные запросы (AsyncTask) что-бы приложение не подвисало. Кроме того к авторизации надо прикрутить SSL, абстрагироваться http-запроса выделив его в отдельный класс если данные будут запрашиваться часто. И встроить в Activity производный от него класс что-бы получать доступ к Activity-методам.. выглядит это в примерно так

1636.png

А что-бы процесс было видно пользователю — можно добавить ProgressBar диалог..

this.progressDialog = new ProgressDialog(MyKillerActivity.this); //диалог в контексте страницы
//учитываем локализацию
this.progressDialog.setMessage(getApplicationContext().getResources().getString(R.string.dialog_logging_in));
this.progressDialog.show();
...
protected void onPostExecute(Object responce){
    this.progressDialog.dismiss(); //когдм AsyncTask заканчивается - прячем диалог
}

Храним настройки (SharedPreferences)

Настройки приложения вовсе не значат управление ими пользователем через интерфейс (для этого есть странички типа PreferenceActivity). Настройки это один из видов постоянного хранения данных наряду с файлами и SQLite. С их помощью можно хранить данные между запусками

SharedPreferences settings = getSharedPreferences("MyKillerAppSettings", MODE_PRIVATE);
settings.edit().putString("MyMinionName", MyKillerActivity.minionName).commit(); //пишем
settings.getString("MyMinionName",""); //читаем

Полезно по теме

1598.png1605.png