Android

Android — ОС для коммуникаторов, планшетных компьютеров, электронных книжек, цифровых проигрывателей, наручных часов, нетбуков и смартбуков, основанная на ядре Linux. Android позволяет создавать Java-приложения, управляющие устройством через разработанные Google библиотеки.

В силу того, что очень активно эта область развивается, стало интересно, что это за зверь такой. Решил посмотреть как оно – создавать приложения под Android. Как оказалось, занятная штука.

Первое знакомство

Мне вообще довольно сложно переходить с одной технологии на другой, так как довольно консервативен по натуре. Обычно изучение языка/технологии происходит, если я вижу, что это интересно/прибыльно. В случае с Android, это оказалось действительно интересно, к тому же в планах приложения платные писать.

Предполагал, что будут трудности уже на этапе установки/настройки. Настройка и установка окружения для работы с Android оказалась не хлопотным занятием. Сама установка без SDK меньше часа занимает, после чего можно уже спокойно начинать изучать среду. Больше времени занимает скачивание и установка SDK.

Ну вот, всё установлено, сразу встаёт вопрос, а под какую версию писать то? Для этого необходимо знать процентов юезров той или иной версии Android. К счастью, Google публикует эту статистику.

Статистика по версиям

Статистика пользователей Android по версиям - октябрь 2014

Версия Название API Доля
2.2 Froyo 8 0.7%
2.3.3 – 2.3.7 Gingerbread 10 11.4%
4.0.3 – 4.0.4 Ice Cream Sandwich 15 9.6%
4.1.x Jelly Bean 16 25.1%
4.2.x 17 20.7%
4.3 18 8.0%
4.4 KitKat 19 24.5%

Доля смартфонов, основанных на Android 4.0 растет достаточно быстро, отнимая позиции у более старых версий ОС. В тоже время Android 2.3 занимает прочные позиции и скорее всего еще не скоро уйдет со сцены, приводя к еще большей фрагментации платформы Android.

Как видно, до сих пор много юзеров Android сидят на 2.3 Gingerbread. Так что, пока приходится поддерживать 2.3 устройства в своих приложениях =/

Метрики в Android

  • px (пиксели): точки на экране.
  • in (дюймы): Размеры, измеряемые линейкой.
  • mm (миллиметры): Размеры, измеряемые линейкой.
  • pt (точки): 1/72 дюйма.
  • dp/dip (независящие от плотности экрана пиксели): абстрактные пиксели, зависящие от плотности экрана. При плотности экрана 120 точек на дюйм (120 dpi), 1dp = 1px.
  • sp (пиксели, независящие от масштаба): похожи на dp, но учитывают размер шрифта, установленный пользователем.

Очевидно, что юзать пиксели не вариант, ибо размеры экрана разные на устройствах. Я бы советовал вообще задавать размеры везде относительные, юзая weight, но если не получается, то лучше использовать sp для текста, dp для других элементов

Полезные исходники, примеры

Исходники, примеры, которые могут быть полезны при разработке. Большая часть из собственного опыта.

Перезапуск приложения

Бывает, что есть необходимость перезапустить своё приложение. В моём случае, мне это понадобилось, чтобы настройки приложения вошли в силу. Когда юзер меняет в настройках язык приложения, проще перезапустить приложение, чтоб Android потом в соответствии с выбранным Locale соответствующие языковые настройки подрубил.

Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

Определение выбора пользователя в настройках и действия в соответствии с этим

Иногда необходимо производить какие-то действия после изменений настроек. Для этого можно подписаться на изменение, затем какие-то действия производить. Как пример, при выборе другого шрифта вносить изменения в оформление приложения. В принципе, при закрытии окна настроек и при переходе на другое Activity Android вызовет метод onCreate, где уже новые настройки вступят в силу.

Но в случае с тем же Locale не пройдёт такой метод. Как я понял, выбор языка происходит при запуске приложения. Для смены оного необходимо ребутать приложение.

SharedPreferences.OnSharedPreferenceChangeListener prefListener = 
  new SharedPreferences.OnSharedPreferenceChangeListener() 
{
   public void onSharedPreferenceChanged(SharedPreferences prefs,String key) 
   {
      if(key.equals("наименование_параметра")) 
      {
         //что-то делаем
      }
   }
};

OnSharedPreferenceChangeListener срабатывает каждый раз при выборе какого-то пункта в окне настроек. Можно ещё переопределить глобальный метод onConfigurationChanged.

public void onConfigurationChanged(Configuration newConfig) 
{
   //что-то делаем
   super.onConfigurationChanged(newConfig);
}

Он будет срабатывать при изменениях в приложении. Изменения, за которыми необходимо следить, прописываются в манифесте в необходимом Activity.

android:configChanges="locale|orientation"

Если это прописать в манифесте Activinty, то при изменении языка или повороте экрана устройства, будет срабатывать onConfigurationChanged.

Как программно задать значение параметра в dip?

Когда вы задаёте параметры элементов в xml, то траблов нет. А вот программно все методы по манипуляции параметрами у View оперирует пикселями, что не есть хорошо. Что же делать? Что же делать?

Создать файл dimens.xml с таким содержанием:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="margin_left">2dp</dimen>
</resources>

И потом использовать это значение в коде, как пример для задания отступов:

TableRow.LayoutParams params = new TableRow.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT, 1);
params.setMargins(0, 0, 0, (int) getResources().getDimension(R.dimen.my_margin_left));

dip налету в пиксели преобразуется =3

Как программно задать значение параметра Weight?

При разработке приходится интерфейс создавать программно порой. Стандартного метода setWeight нет, всё настраивается на уровне LayoutParams. Как пример, зададим weight для TextView:

TableRow.LayoutParams param =  new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.2f);
TextView tv = new TextView(this);
tv.setLayoutParams(param);

Тут важно отметить, какой именно LayoutParams вы юзаете. Если ваш TextView будет внутри TableRow, то юзайте TableRow.LayoutParams. Если внутри RelativeLayout, то RelativeLayout.LayoutParams. Ну, и т.д.

Задать Scroll элементу

Если блок с данными большой, то есть необходимость прикрепить скролл к нему. В том же TableLayout стандартного нет. Если хотите скролл добавить, то запихните ваш TableLayout в ScrollView. Если хотите горизонтальный Scroll, то запихните TableLayout в HorizontalScrollView, который запихните в ScrollView.

Ярлыки на разные Activity одного приложения

Интересная штука в Android есть. Можно создать несколько иконок для одного приложения, которые будут вызывать различные Activity.

Вообще архитектура взаимодействия Activity такова, что даже в рамках одного приложения все Activity относительно независимы и могут являться точкой входа. Собственно в mainfest.xml можно указать точку входа для приложения.

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Если прописать в несколько Activity, то на телефоне появятся иконки для каждого Activity, для которого мы intent‘ы эти прописали.