Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
qrcode

Программирование под Android. Для профессионалов


Скачать 19.35 Mb.
НазваниеПрограммирование под Android. Для профессионалов
АнкорBrayn Khardi Bill Fillips - Programmirovanie po.
Дата23.05.2017
Размер19.35 Mb.
Формат файлаpdf
Имя файлаBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.pdf
оригинальный pdf просмотр
ТипДокументы
#21061
страница36 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   32   33   34   35   36   37   38   39   ...   55
Глава 23. Подробнее об интентах и задачах неявный интент с использованием startActivity(…)
(или startActivityForRe- sult(…)
), ОС незаметно включает в интент категорию
Intent.CATEGORY_DEFAULT
Таким образом, если вы хотите, чтобы фильтр интентов соответствовал неявным интентам, отправленным через startActivity(…)
, вы должны включить в этот фильтр интентов категорию
DEFAULT
Активность с фильтром интентов
MAIN/LAUNCHER
является главной точкой входа приложения, которому она принадлежит. Для нее важно лишь то, что она явля- ется главной точкой входа приложения, а является ли она главной точкой входа
«по умолчанию» — несущественно, поэтому она не обязана включать категорию
CATEGORY_DEFAULT
Так как фильтры интентов
MAIN/LAUNCHER
могут не включать
CATEGORY_DEFAULT
, надежность их соответствия неявным интентам, отправленным вызовом startAc- tivity(…)
, не гарантирована. Поэтому мы используем интент для прямого запроса у
PackageManager информации об активностях с фильтром интентов
MAIN/LAUNCHER
Следующий шаг — отображение меток этих активностей в списке
ListView экзем- пляра
NerdLauncherFragment
. Метка (label) активности представляет собой ото- бражаемое имя — нечто, понятное пользователю. Если учесть, что эти активности являются активностями лаунчера, такой меткой, скорее всего, должно быть имя приложения.
Метки активностей вместе с другими метаданными содержатся в объектах
Re- solveInfo
, возвращаемых
PackageManager
Сначала добавьте следующий код для сортировки объектов
ResolveInfo
, воз- вращаемых
PackageManager
, в алфавитном порядке меток, получаемых методом
ResolveInfo.loadLabel(…)
Листинг 23.3. Алфавитная сортировка (NerdLauncherFragment.java)
Log.i("NerdLauncher", "I've found " + activities.size() + " activities.");
Collections.sort(activities, new Comparator() {
public int compare(ResolveInfo a, ResolveInfo b) {
PackageManager pm = getActivity().getPackageManager();
return String.CASE_INSENSITIVE_ORDER.compare(
a.loadLabel(pm).toString(),
b.loadLabel(pm).toString());
}
});
Затем создайте объект
ArrayAdapter
, который создаст простые представления эле- ментов списка с метками активностей, и назначьте этот адаптер
ListView
Листинг 23.4. Создание адаптера (NerdLauncherFragment.java)
Collections.sort(activities, new Comparator() {
}
});

Создание явных интентов на стадии выполнения
387
ArrayAdapter adapter = new ArrayAdapter(
getActivity(), android.R.layout.simple_list_item_1, activities) {
public View getView(int pos, View convertView, ViewGroup parent) {
View v = super.getView(pos, convertView, parent);
// В документации сказано, что simple_list_item_1
// является TextView; преобразуем для задания текстового значения.
TextView tv = (TextView)v;
ResolveInfo ri = getItem(pos);
tv.setText(ri.loadLabel(pm));
return v;
}
};
setListAdapter(adapter);
Запустите приложение NerdLauncher; вы увидите список
ListView
, заполненный метками активностей.
Рис. 23.2. Список активностей
Создание явных интентов на стадии выполнения
Мы использовали неявный интент для сбора информации об активностях и выводе ее в формате списка. Следующим шагом должен стать запуск выбранной активно- сти при нажатии пользователем на элементе списка. Для запуска активности будет использоваться явный интент.

388
Глава 23. Подробнее об интентах и задачах
Для создания явного интента нам потребуются дополнительные данные из
ResolveInfo
— в частности, имя пакета и имя класса активности. Эти данные мож- но получить из части
ResolveInfo с именем
ActivityInfo
. (О том, какие данные доступны в разных частях
ResolveInfo
, можно узнать из документации.)
В файле
NerdLauncherFragment.java переопределите метод onListItemClick(…)
для по- лучения объекта
ActivityInfo для элемента списка. Затем используйте его данные для создания явного интента, запускающего активность.
Листинг 23.5. Реализация onListItemClick(…) (NerdLauncherFragment.java)
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
ResolveInfo resolveInfo = (ResolveInfo)l.getAdapter().getItem(position);
ActivityInfo activityInfo = resolveInfo.activityInfo;
if (activityInfo == null) return;
Intent i = new Intent(Intent.ACTION_MAIN);
i.setClassName(activityInfo.applicationInfo.packageName, activityInfo.name);
startActivity(i);
}
Обратите внимание: в этом интенте мы отправляем действие как часть явного интен- та. Большинство приложений ведет себя одинаково независимо от того, включено действие или нет, однако некоторые приложения могут изменять свое поведение.
Одна и та же активность может отображать разные интерфейсы в зависимости от того, как она была запущена. Вам как программисту лучше всего четко объявить свои намерения и позволить активностям запуститься так, как они считают нужным.
В листинге 23.5 мы получаем имя пакета и имя класса из метаданных и используем их для создания явной активности методом
Intent
:
public Intent setClassName(String packageName, String className)
Этот способ отличается от того, который использовался нами для создания явных интентов в прошлом. Ранее мы использовали конструктор
Intent
, получающий объекты
Context и
Class
:
public Intent(Context packageContext, Class cls)
Этот конструктор использует свои параметры для получения
ComponentName
— имени пакета, объединенного с именем класса. Когда вы передаете
Activity и
Class для создания
Intent
, конструктор определяет полное имя пакета по
Activity
Также можно самостоятельно создать
ComponentName по именам пакета и класса и использовать следующий метод
Intent для создания явного интента:
public Intent setComponent(ComponentName component)
Однако решение с методом setClassName(…)
, автоматически создающим имя ком- понента, получается более компактным.
Запустите NerdLauncher и посмотрите, как работает запуск приложений.

Задачи и стек возврата
389
Задачи и стек возврата
Android использует задачи для отслеживания текущего состояния пользователя в каждом выполняемом приложении. Задача (task) представляет собой стек актив- ностей, с которыми имеет дело пользователь. Активность в нижней позиции стека называется базовой активностью, а активность в верхней позиции видна пользовате- лю. При нажатии кнопки
Back верхняя активность извлекается из стека. Если нажать кнопку
Back при просмотре базовой активности, вы вернетесь к домашнему экрану.
Диспетчер задач позволяет переключаться между задачами без изменения состояния каждой задачи. Например, если вы начинаете вводить новый контакт и переключа- етесь на проверку своей публикации в Твиттере, будут запущены две задачи. При переключении на редактирование контактов сохраняется ваша текущая позиция в обеих задачах.
Иногда запускаемая активность должна добавляться к текущей задаче. В других случаях она должна запускаться в новой задаче, независимой от запустившей ее активности.
Запуск активности
Нажатие кнопки Back
Запуск активности
(с флагом новой задачи)
Рис. 23.3. Задачи и стек возврата

390
Глава 23. Подробнее об интентах и задачах
По умолчанию новые активности запускаются в текущей задаче. В приложении
CriminalIntent все запускавшиеся активности добавлялись к текущей задаче. Это относилось даже к активностям, которые не являлись частью приложения Crim- inalIntent (например, при запуске активности для отправки отчета). Преимущество добавления активности к текущей задаче заключается в том, что пользователь мо- жет выполнять обратную навигацию внутри задачи, а не в иерархии приложений.
В текущей версии все активности, запускаемые из NerdLauncher, добавляются в задачу NerdLaucher. Чтобы убедиться в этом, запустите CriminalIntent из Nerd-
Launcher и вызовите диспетчер задач. (Нажмите кнопку
Recents
, если она имеется на устройстве; в противном случае используйте долгое нажатие кнопки
Home
.)
Вы не найдете в списке CriminalIntent. Запущенная активность
CrimeListAc- tivity была добавлена в задачу NerdLauncher. Нажатие на задаче NerdLauncher вернет вас к экрану CriminalIntent, который вы просматривали перед запуском диспетчера задач.
Рис. 23.4. Приложение CriminalIntent не выполняется в отдельной задаче
Мы хотим, чтобы приложение NerdLauncher запускало активности в новых задачах.
Далее пользователь может переключаться между выполняемыми приложениями так, как считает нужным. Чтобы при запуске новой активности запускалась новая задача, следует добавить в интент соответствующий флаг.
Запустите приложение NerdLauncher и выберите CriminalIntent. На этот раз при вызове диспетчера задач становится видно, что CriminalIntent выполняется в от- дельной задаче.

Использование NerdLauncher в качестве домашнего экрана
391
Листинг 23.6. Добавление флага в интент (NerdLauncherFragment.java)
Intent i = new Intent(Intent.ACTION_MAIN);
i.setClassName(activityInfo.applicationInfo.packageName, activityInfo.name);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
Рис. 23.5. CriminalIntent выполняется в собственной задаче
Повторный запуск CriminalIntent из NerdLauncher не приведет к созданию второй задачи CriminalIntent. Флаг
FLAG_ACTIVITY_NEW_TASK
создает только одну задачу на активность. У
CrimeListActivity уже имеется работающая задача, поэтому Android переключится на эту задачу вместо запуска новой.
Использование NerdLauncher в качестве
домашнего экрана
Но кому захочется запускать приложение, чтобы запускать другие приложения?
Гораздо логичнее использовать NerdLauncher как замену для домашнего экрана устройства. Откройте файл
AndroidManifest.xml в
NerdLauncher и добавьте следующий фрагмент в главный фильтр интентов.
Листинг 23.7. Изменение категорий NerdLauncher (AndroidManifest.xml)


продолжение


392
Глава 23. Подробнее об интентах и задачах




Добавление категорий
HOME
и
DEFAULT
означает, что активность NerdLauncher долж- на включаться в число вариантов домашнего экрана. Нажмите кнопку
Home и вам будет предложено использовать NerdLauncher.
(Если вы назначите NerdLauncher домашним экраном, а потом захотите отменить свой выбор, выполните команду
Settings

Applications

Manage
Applications
. Выберите
All
, найдите NerdLauncher и сбросьте режим запуска по умолчанию
Launch by default
. При следующем нажатии кнопки
Home вы сможете выбрать новый домашний экран по умолчанию.)
Упражнение. Значки, изменение порядка задач
В этой главе мы использовали метод
ResolveInfo.loadLabel(…)
для отображения содержательных имен в лаунчере. Класс
ResolveInfo предоставляет аналогичный метод loadIcon()
для получения значка, отображаемого для каждого приложения.
Вам предлагается несложное упражнение: снабдить каждое приложение в Nerd-
Launcher значком.
Если вам захочется большего, добавьте в NerdLauncher другую активность для переключения между выполняемыми задачами. Для этого используйте системную службу
ActivityManager
, которая предоставляет информацию об активностях, зада- чах и приложениях, выполняемых в настоящее время. В отличие от
PackageManager класс
Activity не предоставляет вспомогательного метода getActivityManager()
для получения доступа к этой системной службе.
Вместо этого для получения объекта
ActivityManager следует вызвать
Activity.
getSystemService()
с передачей в параметре константы
Activity.ACTIVITY_SERVICE
Вызовите getRunningTasks()
для получения списка выполняемых задач, упоря- доченных по времени запуска (от новых к старым). Чтобы вывести одну из таких задач на передний план, вызовите метод moveTaskToFront()
. Обязательно сверьтесь со справочной документацией Android — для переключения между задачами в ма- нифест приложения необходимо добавить дополнительное разрешение.
Для любознательных: процессы и задачи
Для существования любого объекта необходима память и виртуальная машина.
Процесс
представляет собой место, созданное ОС, в котором существуют объекты вашего приложения и в котором выполняется само приложение.
Процессам могут принадлежать ресурсы, находящиеся под управлением ОС — па- мять, сетевые сокеты, открытые файлы и т. д. Процесс также содержит минимум один (а вероятно, несколько) программный поток (thread). На платформе Android процесс всегда выполняется ровно на одной виртуальной машине Dalvik.

Для любознательных: процессы и задачи
393
Как правило, каждый компонент приложения в Android связывается ровно с од- ним процессом (хотя встречаются довольно смутные исключения). Приложение создается с собственным процессом, который становится процессом по умолчанию для всех компонентов приложения.
Отдельные компоненты можно назначать разным процессам, но мы рекомендуем придерживаться процесса по умолчанию. Если вы думаете, что какой-то код должен выполняться в другом процессе, аналогичного результата обычно удается добиться с использованием многопоточности (multi-threading), которая программируется в Android намного проще, чем многопроцессное выполнение.
Каждый экземпляр активности существует ровно в одном процессе и ровно в од- ной задаче. Впрочем, на этом все сходство и завершается. Задачи содержат только активности и часто состоят из активностей разных приложений. С другой стороны, процессы содержат только выполняемый код и объекты приложения.
Процессы и задачи легко спутать, потому что эти концепции отчасти перекрываются, а для ссылок на них часто используются имена приложений. Например, при запуске
CriminalIntent из NerdLauncher ОС создает процесс
CriminalIntent и новую задачу, для которой
CrimeListActivity является базовой активностью. В диспетчере задач эта задача снабжается меткой
CriminalIntent
Задача, в которой существует активность, может быть не связана с процессом, в котором она существует. Когда мы запустили контактное приложение для выбора подозреваемого в CriminalIntent, оно было запущено в задаче CriminalIntent — но при этом выполнялось в процессе контактного приложения.
(активность
контактного
приложения)
Задача CriminalIntent
(Процесс приложения
CriminalIntent)
(Процесс контактного приложения)
Рис. 23.6. Задачи и процессы
Это означает, что когда пользователь нажимает кнопку
Back для перехода между раз- ными активностями, он может незаметно для себя переключаться между процессами.
В этой главе мы создавали задачи и переключались между ними. Как насчет унич- тожения задач или замены стандартного диспетчера задач Android? К сожалению,
Android не предоставляет средств для решения любой из этих задач. Долгое на- жатие на кнопке
Home жестко связано с диспетчером задач по умолчанию, а задачи уничтожаться не могут. Процессы, напротив, могут уничтожаться. Приложения, рекламируемые в магазине Google Play как уничтожители задач, в действительности являются уничтожителями процессов.

Стили и включения
Хотя вашей первоочередной целью является нормальное функционирование приложения, не стоит забывать и о том, как приложение смотрит- ся и насколько удобно с ним работать. Рынок при- ложений огромен, и хороший пользовательский интерфейс может выделить ваше приложение на фоне конкурентов.
Даже если пользовательский интерфейс спроек- тирован специалистом, вы должны реализовать его. В этой будут рассмотрены некоторые инстру- менты, помогающие быстро создать прототип ди- зайна приложения. Работая с профессиональным дизайнером, вы будете знать, чего от него требо- вать и как использовать созданные им ресурсы.
В этих двух главах мы создадим приложение, имитирующее телевизионный пульт дистанцион- ного управления. Впрочем, ничем управлять оно не будет; это всего лишь тренажер для отработки навыков проектирования дизайна. В этой главе мы используем стили и включения для создания пульта, изображенного на рис. 24.1.
Приложение RemoteControl содержит только одну активность, изображенную на рис. 24.1.
В верхней части пульта выводится текущий канал.
Ниже находится область, в которой новый канал отображается в процессе ввода.
Нажатие кнопки
Delete очищает область ввода канала. Кнопка
Enter изменяет канал с обновлением области текущего канала и очисткой области ввода.
Рис. 24.1. Приложение
RemoteControl
24

Создание проекта RemoteControl
395
Создание проекта RemoteControl
Создайте новый проект
Android
Application и настройте его параметры, как показано на рис. 24.2.
Рис. 24.2. Создание проекта RemoteControl
Прикажите мастеру создать пустую активность с именем
RemoteControlActivity
Создание RemoteControlActivity
Так как класс
RemoteControlActivity будет субклассом
SingleFragmentActivity
, скопируйте файл
SingleFragmentActivity.java из проекта CriminalIntent в пакет com.
bignerdranch.android.remotecontrol
. Затем скопируйте файл activity_fragment.xml в каталог res/layout проекта RemoteControl.
Откройте файл
RemoteControlActivity.java
. Назначьте класс
RemoteControlActivity субклассом
SingleFragmentActivity
; он будет создавать экземпляр
RemoteControl-
Fragment
. (Вскоре мы создадим этот класс фрагмента). Наконец, переопределите метод
RemoteControlActivity.onCreate(…)
, чтобы он скрывал панель действий или панель заголовка активности.
Листинг 24.1. Создание класса RemoteControlActivity (RemoteControlActivity.java)
public class RemoteControlActivity extends Activity SingleFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
продолжение


396
1   ...   32   33   34   35   36   37   38   39   ...   55

перейти в каталог файлов

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей