Статьи

Android-приложение для мониторинга Hudson — часть II конфигурации

На прошлой неделе было продемонстрировано создание приложения для Android, которое запрашивало удаленный API Hudson через вызовы REST, которые возвращали объекты JSON; в приложении для Android для мониторинга Hudson Rest API . Приложение было очень простым, все, что можно было сделать, это запустить его, и не было никаких настроек или настроек, чтобы сделать приложение более удобным для пользователя. На этой неделе приложение будет расширено для использования меню и добавления дополнительных экранов или действий, позволяющих пользователю настроить приложение так, чтобы оно указывало на удаленный сервер Hudson по своему выбору. Приложение также сохранит состояние конфигурации, чтобы пользователю не приходилось повторно вводить информацию после завершения работы приложения.

Первым шагом в настройке приложения будет избавление от значка Android по умолчанию и размещение настраиваемого значка. Android поддерживает форматы изображений .jpg, .gif, .png и .bmp. Чтобы настроить значок по умолчанию, просто откройте папку res / drawable и поместите изображение в эту папку. Изображение должно быть размером 48×48 .PNG.

 

Откройте файл AndroidManifest.xml и редактировать андроид: значок атрибут быть андроидом: значок =»@ вытяжка / youriconname» . Обратите внимание, что расширение .PNG не включено в название. Ресурсы компилируются в конечное приложение и идентифицируются по структуре папок, в которой находится файл в каталоге res /. Основным для этого приложения являются рисование, меню, макет, значения (простые значения).

Пример Launch Icon.

 

 
Существует три основных типа меню. Опции меню, которые активируются нажатием клавиши меню. Контекстное меню, которое отображается при длительном нажатии на приложение. Это похоже на опцию меню правой кнопки мыши на компьютере. Затем, наконец, подменю, которое можно добавить к любому пункту меню, кроме другого подменю; Примером является вложенность меню. Это простое приложение, поэтому оно будет использовать только меню параметров. Одна опция для настроек, а другая для обновления списка.

В основной класс активности листинга (SpyHudson.java) добавьте метод обратного вызова onCreateOptionsMenu (меню Меню) . Этот метод отменяет создание родительского меню и модифицируется для добавления двух необходимых нам пунктов меню. Таким образом, чтобы создать уникальные идентификаторы, для которых был выбран пункт меню, мы объявим две константы, для пункта меню настройки и другую для обновления.

private static final int ACTIVITY_SETUP = Menu.FIRST; 
private static final int ACTIVITY_REFRESH = Menu.FIRST + 1;

Измените и добавьте следующее к обратному вызову onCreateOptionsMenu.

/* Creates the menu items */
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ACTIVITY_SETUP, 0,"Setting");
menu.add(1,ACTIVITY_REFRESH,0,"Refresh");
return true;
}

Первый параметр в меню добавления просто назначает элемент группе меню, второй — уникальный идентификатор меню, ноль — порядок появления элементов меню, а строка — то, каким будет отображаемое имя элемента меню. Альтернативой написанию текста в коде является ссылка на него как на ресурс, добавление его в файл res / values ​​/ strings.xml и обращение к нему: getString (R.string. Setting )

Модификация тогда будет:

public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ACTIVITY_SETUP, 0, getString(R.string.setting_menu));
menu.add(0,ACTIVITY_REFRESH,1, getString(R.string.refresh_menu));
return true;
}

Теперь, чтобы обработать действия меню, это делается путем добавления обратного вызова метода onOptionsItemSelected (Menu). Если вы работали со свингом, это событие экшн. Объект Menu при вызове имеет идентификатор элемента, который мы объявили ранее и который можно использовать в операторе switch этого метода. Выбранный пункт меню «Настройки» вызовет changeSettings (). Опция меню «Обновить» вызовет метод refreshView (). Интересно, что onOptionsItemSelected ожидает логическое возвращаемое значение. False позволяет продолжить нормальную обработку, а true указывает на то, что обрабатывать процесс здесь. Как и Swing не является поточно-ориентированным, то же самое относится и к пользовательскому интерфейсу Android, поэтому вам нужно быть немного более точным в отношении того, где вы хотите, чтобы пользовательский интерфейс удерживался.

  

       /* Handles item selections */
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case ACTIVITY_SETUP:
changeSetting();
return true;
case ACTIVITY_REFRESH:
refreshView();
return true;
}
return false;
}

  Полученное меню будет выглядеть примерно так:

Вызов changeSettings () будет рассмотрен чуть позже.

SharedPreferences — это интерфейс, который позволяет приложению Android сохранять состояние предпочтений в хэш-карту, которую можно сохранять и извлекать по мере необходимости. Используйте getSharedPreferences («preference_filename», mode_id), чтобы получить ссылку на этот интерфейс. Имя файла настроек — любая строка, и идентификатор режима по умолчанию должен быть 0. Режим 1 указывает, что файл настроек затем доступен для чтения другими приложениями для Android, а режим 2 указывает, что он доступен для записи другими приложениями для Android. В большинстве случаев режим должен быть 0, так как настройки должны быть частными для текущего приложения Android.

Доступ к значению предпочтения такой же, как у объекта свойств java. Просто вызовите sharedpreference.getString («имя ключа», «значение по умолчанию»).

Результатом представления обновления являются следующие два метода:

        private void refreshView() {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String remoteUrl = settings.getString("serverurl", "http://localhost:8080/hudson/api/json");
this.refreshView(remoteUrl);
}

private void refreshView(String url) {
ArrayList<JSONObject> jobs = spyRest.retrieveJSONArray(url);
setListAdapter(new ImageTextListAdapter(this,jobs));
}

Обратите внимание, что мы просто переместили две строки в конец onCreate (Bundle), где он вызывает удаленный URL, и переместили его в этот новый метод.

Сохранить в файл настроек просто, как получить SharedPreferences.Editor, поместив в него имя ключа и строковое значение. Сделайте специальную заметку, чтобы вызвать editor.commit () для сохранения данных. Это делается в вызове метода savePreferences.

private void savePreferences(String value) {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("serverurl", value);
// Don't forget to commit your edits!!!
editor.commit();
}

 
Каждый экран в Android — это активность. Поэтому мы хотим создать еще один экран для настройки URL-адреса сервера, который мы хотели бы запросить на сервере Hudson CI. Сначала создайте макет в res / layout, и он будет иметь текст с полем для редактирования и кнопку. Здесь навыки управления макетом становятся необходимыми; расположение компонентов для приложения, которое может быть развернуто на множестве размеров экрана, необходимо учитывать в различных вариантах.

Это следующий макет:

 

 Поддерживающий макет XML для этой формы выглядит следующим образом:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/server_title" />
<EditText android:text="@string/server_url_text" android:id="@+id/serverurl"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>

<Button android:text="@string/confirm_btn" android:id="@+id/confirmbtn"
android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>

Следующим шагом является создание класса интерактивной активности AppSettingActivity. Как и все классы активности, мы переопределим и добавим обратный вызов onCreate (Bundle). Нам нужно получить отредактированный текст и перезаписать текст по умолчанию информацией в наших настройках, чтобы сделать это, используя findViewById (), передавая в него ссылочный идентификатор. Это вернет объект представления из макета XML, который затем может быть приведен к объекту EditText. Там текст для поля редактирования может быть установлен. Это все делается в вызове onCreate (Bundle) в упражнении:

     editTextServerUrl = (EditText) findViewById(R.id.serverurl);

SharedPreferences settings = getSharedPreferences(SpyHudson.PREFS_NAME, 0);
String remoteUrl = settings.getString("serverurl", "http://localhost:8080/hudson/api/json");
editTextServerUrl.setText(remoteUrl);

 
Затем добавьте прослушиватель щелчка к кнопке, чтобы при нажатии на нее текст сохранялся в связке, которую можно передать обратно в вызывающее намерение, и закрывайте это действие. Объекты намерений — это привязки к действиям или переход между жизненным циклом действий. Об интенциях поговорим через минуту. На данный момент дополнительная информация о поле редактирования будет помещена в пакет отображения строк. Это должно продемонстрировать, как работает связывание между действиями. Другой вариант — просто использовать SharedPreferences и сохранять значение редактируемого текста прямо в настройках, поскольку мы использовали его для извлечения ранее сохраненной информации из него.

        Button confirmButton = (Button) findViewById(R.id.confirmbtn);
confirmButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {
Bundle bundle = new Bundle();

bundle.putString("server", editTextServerUrl.getText().toString());

Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
finish();
}

});

 
Это почти завершает заявку. Последний шаг — подключение действия к основному приложению, требуется добавление его в манифест приложения. Если вы забудете добавить это в AndroidManifest.xml, вы получите приложение, которое выдает ошибку и просит «принудительно закрыть» его, когда оно пытается запустить действие. Помните, что приложение может иметь одно или несколько действий.

 (Посмотрите, как действие .SettingsActivity, которое является именем класса, добавляется в приложение)

  <application android:label="@string/app_name" android:icon="@drawable/hudson">
<activity android:label="@string/app_name" android:name=".SpyHudson">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AppSettingActivity"/>
</application>

Помните метод changeSettings () в классе SpyHudson. Мы добавим Намерение запуска AppSettingActivity и будем отслеживать его на предмет возвращения активности. Вот как это выглядит:

       private void changeSetting() {
Intent i = new Intent(this, AppSettingActivity.class);
startActivityForResult(i, ACTIVITY_SETUP);
}

Вызов startActivityForResult запускает действие AppSettingActivity, и после завершения действия будет сделан вызов onActivityResult (). Этот вызов метода должен быть переопределен родительским классом.

После того, как действие вернется, мы хотим получить дополнительную информацию об объекте, потому что, как вы помните, у него была информация о сервере. Это внутри объекта Bundle. Затем сохраните эту строку в предпочтении, вызвав вызов метода savePreferene (), созданный ранее, и обновите представление списка, вызвав метод refreshView (). Вот как это выглядит:

       @Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();
switch (requestCode) {
case ACTIVITY_SETUP:
String serverUrl = extras.getString("server");
this.savePreferences(serverUrl);
refreshView(serverUrl);
break;
}
}

Запустите приложение, и оно должно иметь два пункта меню. Параметр меню настройки выводит пользователя на экран, чтобы заполнить URL-адрес hudson, который он хочет запросить, и эта информация сохраняется в локальных настройках приложения.

Это приложение действительно простое и затрагивает некоторые основные элементы приложения Android. Он не имеет всех элементов, позволяющих отлавливать ошибки тайм-аутов сети и обрабатывать пользовательский ввод неверно искаженных URL-адресов, поскольку снова представляет собой презентацию возможного приложения для платформы Android, которое взаимодействует с REST API Hudson.