Top Banner
ANDROID open source developer-friendly mobile operational system
31
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: First Android Mini-party (Part I)

ANDROIDopen source developer-friendly

mobile operational system

Page 2: First Android Mini-party (Part I)

Android first mini party

2

Содержание

Общее впечатление от Android Пример архитектуры приложения (I

часть)

Page 3: First Android Mini-party (Part I)

ОБЩЕЕ ВПЕЧАТЛЕНИЕ ОТ ANDROID

Наше самое субъективное мнение

Page 4: First Android Mini-party (Part I)

Android first mini party

4

Что знает каждый

Открытость системы (≈4GB of sources) По-настоящему большое число устройств Новая версия ОС каждые полгода-год Легкость разработки, хорошая

документация Java Android market Уникальная модель многозадачности Эксклюзивные плюшки от Google

Page 5: First Android Mini-party (Part I)

Android first mini party

5

Что в действительности (1/3)

Производители Они любят копаться в коде Они точно знают, как сделать лучше Их интересуют деньги, а не платформа и это

нормально Google им попустительствует и это не

нормально Много девайсов

Вам правда потребуется много девайсов Аппаратные функции телефона тестируются на

устройствах screen resolution, CPU, hardware keyboard, etc.

Page 6: First Android Mini-party (Part I)

Android first mini party

6

Что в действительности (2/3) Новая версия ОС каждые полгода-год

Новая ОС — новый девайс Support придумали дураки Backward compatibility

Открытость Вседозволенность разработчиков Безумные идеи заказчиков Претензии начальников Нерадивые производители

Java Тормозит? Аппараты от 1GHz Никогда не поздно вспомнить JNI и C/C++

Page 7: First Android Mini-party (Part I)

Android first mini party

7

Что в действительности (3/3) Прочие подводные камни

Это мультизадачность, сынок, готовься к смерти

Как передать данные от Activity к Activity? А какой же здесь Context? (Смена

ориентации) I WANT TO SEARCH! RIGHT NOW! Activity lifecycle SD-Card mount/unmount MediaAPI (я никогда не устану это

повторять:)

Page 8: First Android Mini-party (Part I)

Android first mini party

8

Примеры

Один INSERT в Sqlite на Galaxy S занимает около секунды - что-то не получилось с файловой системой

MediaRecorder.start() с выводом в AMR_NB на DROID X или зависал на стопе или искажал звук

MediaRecorder.stop() на Motorola Milestone после 10 минут не хотел выполняться

MediaRecorder.init() на Motorola Milestone с неправильными параметрами убивал камеру до следующего перезапуска

MediaRecorder.setMaxDuration() — who gives a shit? Camera.getParameters() — HashMap<String, String> Падают стандартные приложения

и многое-многое другое…

Page 9: First Android Mini-party (Part I)

Android first mini party

9

Так за что же тогда его любить? За его молодость За работу над ошибками (3.0 мммм:) За открытые исходные коды За его ориентированность на

разработчиков За бесконечные возможности

Page 10: First Android Mini-party (Part I)

ПРИМЕР АРХИТЕКТУРЫ ПРИЛОЖЕНИЯ

Частные решения частых задач

Page 11: First Android Mini-party (Part I)

Android first mini party

11

Задание

Есть сервер, с которого мы получаем данные (tweets).

Мы отображаем эти данные (list of tweets) Мы редактируем старые/создаем новые данные

и отсылаем на сервер (reply/delete/new) Мы периодически синхронизируем данные с

сервером Мы храним данные локально, чтобы приложение

могло быть запущено без интернета Мы предоставляем настройку периодов

синхронизации и какие-то другие параметры

Page 12: First Android Mini-party (Part I)

Android first mini party

12

Общее представление

Server

DB Application

LoginActivity

MainActivity

EditActivity

PreferencesActivity

Page 13: First Android Mini-party (Part I)

Android first mini party

13

А для приготовления нам понадобятся…

Android-sdk-tools скачать как минимум версию 2.1 и Google

APIs android-ndk-tools (для ценителей C/C++)

Eclipse/Idea можно подключить android formatter для

кода ADT plugin (Eclipse) Android Java sources ApiDemos в workspace

Page 14: First Android Mini-party (Part I)

Android first mini party

14

Android-команда

Люси Джефф Борис

Page 15: First Android Mini-party (Part I)

Android first mini party

15

Первая итерация

Получение списка записей пока при старте приложения пока для hardcoded пользователя

Сохранение записей в базу Отображение записей на экране

Page 16: First Android Mini-party (Part I)

Android first mini party

16

Над чем не стоит долго думать

HttpClient, а не java.net.URL SQLite & SQLiteOpenHelper ListView & ListActivity

Page 17: First Android Mini-party (Part I)

17

ListView

Android first mini party

List Adapter

+ getItem();+ getCount();

+ getView();

+ getItemViewType();+ getViewTypeCount();

layout.xml

Page 18: First Android Mini-party (Part I)

Android first mini party

18

Спор Люси и БорисаСобственный Store

DomainObject ArrayAdapter Самостоятельно реализовывать

Observers А как по другому? Там что-то непонятное

написано

Page 19: First Android Mini-party (Part I)

Android first mini party

19

Спор Люси и БорисаContentProvider

Contract & CursorAdapter Observers – DONE

и очень даже крутой Activity.manageCursor()

помощь при с открытием и закрытие Cursor

ContentProvider .openFile () полезный метод для работы с binary data

Page 20: First Android Mini-party (Part I)

20

Android first mini party

ContentProvider. Contractpublic final class ContentContract {

public static final String AUTHORITY = "x.test.content";

public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);

private ContentContract() {

}

protected interface QuestionsColumns {

String GUID = "guid";

/** Active or closed */

String STATE = "state";

/** Rated, Read, Not read, Rejected */

String SUB_STATE = "substate";

String HAS_TRACK = "has_track";

String TRANSCRIPTION = "transcription";

String PRICE = "price";

String POST_DATE = "post_date";

}

public static final class Questions implements QuestionsColumns, BaseColumns {

private Questions() {}

public static class State {

int EDITED = 0, OPENED = 1, CLOSED = 2, DELETED = 3;

}

public static class Substate {

int PENDING = 0, READY_TO_SEND = 1;

}

public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "questions");

public static final String CONTENT_TYPE = "vnd.android.cursor.dir/x.test.question";

public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/x.test.question";

}

Page 21: First Android Mini-party (Part I)

Android first mini party

21

ContentProvider. URI

content:// questions content://questions/# content://questions/opened

content://questions/closed content:// questions/#/answers

content:// questions/#/attachments

ContentProvider.notifyChange(uri)ContentResolver.registerContentObserver(uri, true, observer)

Page 22: First Android Mini-party (Part I)

Android first mini party

22

Вторая итерация

Логин на отдельной LoginActivity и переход на MainActivity

Переход на EditActivity для выбранной записи

Page 23: First Android Mini-party (Part I)

Android first mini party

23

Передача данных между Activity

Исследование Джеффа

Подход Плюсы Минусы

Intent.putExtra(…) • Отправили и забыли• Можно передавать только

примитивные типы и Serializable

Singleton• Доступен из любой части

приложения

• Очень просто получить утечки памяти

• Нет Context’а внутри

Service• Вероятность утечек

памяти существенно ниже• Есть Context

• Необходимость создания и завершения соединения с сервисом

• Затраты на проектирование

Page 24: First Android Mini-party (Part I)

Android first mini party

24

Service. Что же это такое?

Компонент приложения, скрытый от пользователя

Нацелен на выполнения фоновых задач Работает в главном потоке Его можно стартить К нему можно биндиться Его НУЖНО стопить Его ОБЯЗАТЕЛЬНО нужно стопить Процесс, в котором есть застарченный

Service, будет умирать в последнюю очередь

Page 25: First Android Mini-party (Part I)

Android first mini party

25

Service. Local binder

public class LocalService extends Service {

    private final IBinder mBinder = new LocalBinder();    private final Random mGenerator = new Random();

    public class LocalBinder extends Binder {        LocalService getService() {            return LocalService.this;        }    }

    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }

    public int getRandomNumber() {      return mGenerator.nextInt(100);    }}

Page 26: First Android Mini-party (Part I)

Android first mini party

26

Service. Lifecycle

Page 27: First Android Mini-party (Part I)

Android first mini party

27

Проблема Бориса

Thread

Looper

Page 28: First Android Mini-party (Part I)

Android first mini party

28

Решение Люси

Handler

post(Runnable r)

handleMessage(Message m)

obtainMessage()

sendMessage()

Page 29: First Android Mini-party (Part I)

Android first mini party

29

Решение Джеффа

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {     protected Long doInBackground(URL... urls) {         int count = urls.length;         long totalSize = 0;         for (int i = 0; i < count; i++) {             totalSize += Downloader.downloadFile(urls[i]);             publishProgress((int) ((i / (float) count) * 100));         }         return totalSize;     }

     protected void onProgressUpdate(Integer... progress) {         setProgressPercent(progress[0]);     }

     protected void onPostExecute(Long result) {         showDialog("Downloaded " + result + " bytes");     } }

Page 30: First Android Mini-party (Part I)

Android first mini party

30

GOOGLE I/O 2010

Page 31: First Android Mini-party (Part I)

Android first mini party

31

Решение задачи передачи данных

Никакой проблемы передача данных между Activityна самом деле не существует

Activity – это взгляд с разных сторон на данные, которые находятся в Content Provider

Service – это task executor (см. IntentService) Intent – это такс на выполнение, содержащий Action и

URI Service Contract/API – API для взаимодействия с сервисом Service State – singleton для опционального хранения

состояния Service Binder нужен только для частных синхронных операций