first android mini-party (part i)
TRANSCRIPT
Android first mini party
2
Содержание
Общее впечатление от Android Пример архитектуры приложения (I
часть)
Android first mini party
4
Что знает каждый
Открытость системы (≈4GB of sources) По-настоящему большое число устройств Новая версия ОС каждые полгода-год Легкость разработки, хорошая
документация Java Android market Уникальная модель многозадачности Эксклюзивные плюшки от Google
Android first mini party
5
Что в действительности (1/3)
Производители Они любят копаться в коде Они точно знают, как сделать лучше Их интересуют деньги, а не платформа и это
нормально Google им попустительствует и это не
нормально Много девайсов
Вам правда потребуется много девайсов Аппаратные функции телефона тестируются на
устройствах screen resolution, CPU, hardware keyboard, etc.
Android first mini party
6
Что в действительности (2/3) Новая версия ОС каждые полгода-год
Новая ОС — новый девайс Support придумали дураки Backward compatibility
Открытость Вседозволенность разработчиков Безумные идеи заказчиков Претензии начальников Нерадивые производители
Java Тормозит? Аппараты от 1GHz Никогда не поздно вспомнить JNI и C/C++
Android first mini party
7
Что в действительности (3/3) Прочие подводные камни
Это мультизадачность, сынок, готовься к смерти
Как передать данные от Activity к Activity? А какой же здесь Context? (Смена
ориентации) I WANT TO SEARCH! RIGHT NOW! Activity lifecycle SD-Card mount/unmount MediaAPI (я никогда не устану это
повторять:)
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> Падают стандартные приложения
и многое-многое другое…
Android first mini party
9
Так за что же тогда его любить? За его молодость За работу над ошибками (3.0 мммм:) За открытые исходные коды За его ориентированность на
разработчиков За бесконечные возможности
Android first mini party
11
Задание
Есть сервер, с которого мы получаем данные (tweets).
Мы отображаем эти данные (list of tweets) Мы редактируем старые/создаем новые данные
и отсылаем на сервер (reply/delete/new) Мы периодически синхронизируем данные с
сервером Мы храним данные локально, чтобы приложение
могло быть запущено без интернета Мы предоставляем настройку периодов
синхронизации и какие-то другие параметры
Android first mini party
12
Общее представление
Server
DB Application
LoginActivity
MainActivity
EditActivity
PreferencesActivity
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
Android first mini party
15
Первая итерация
Получение списка записей пока при старте приложения пока для hardcoded пользователя
Сохранение записей в базу Отображение записей на экране
Android first mini party
16
Над чем не стоит долго думать
HttpClient, а не java.net.URL SQLite & SQLiteOpenHelper ListView & ListActivity
17
ListView
Android first mini party
List Adapter
+ getItem();+ getCount();
+ getView();
+ getItemViewType();+ getViewTypeCount();
layout.xml
Android first mini party
18
Спор Люси и БорисаСобственный Store
DomainObject ArrayAdapter Самостоятельно реализовывать
Observers А как по другому? Там что-то непонятное
написано
Android first mini party
19
Спор Люси и БорисаContentProvider
Contract & CursorAdapter Observers – DONE
и очень даже крутой Activity.manageCursor()
помощь при с открытием и закрытие Cursor
ContentProvider .openFile () полезный метод для работы с binary data
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";
}
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)
Android first mini party
22
Вторая итерация
Логин на отдельной LoginActivity и переход на MainActivity
Переход на EditActivity для выбранной записи
Android first mini party
23
Передача данных между Activity
Исследование Джеффа
Подход Плюсы Минусы
Intent.putExtra(…) • Отправили и забыли• Можно передавать только
примитивные типы и Serializable
Singleton• Доступен из любой части
приложения
• Очень просто получить утечки памяти
• Нет Context’а внутри
Service• Вероятность утечек
памяти существенно ниже• Есть Context
• Необходимость создания и завершения соединения с сервисом
• Затраты на проектирование
Android first mini party
24
Service. Что же это такое?
Компонент приложения, скрытый от пользователя
Нацелен на выполнения фоновых задач Работает в главном потоке Его можно стартить К нему можно биндиться Его НУЖНО стопить Его ОБЯЗАТЕЛЬНО нужно стопить Процесс, в котором есть застарченный
Service, будет умирать в последнюю очередь
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); }}
Android first mini party
28
Решение Люси
Handler
post(Runnable r)
handleMessage(Message m)
obtainMessage()
sendMessage()
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"); } }
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 нужен только для частных синхронных операций