Статьи

Android-приложение для мониторинга Hudson Rest API


Платформа Android предоставляет привлекательное решение для разработчиков Java.
Его можно развернуть в смартфонах нового поколения, он использует язык Java в синтаксисе и интегрируется в Eclipse. Это уменьшает барьер для входа даже больше, чем J2ME.

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

Если вы еще не установили среду разработки eclipse для Android, это довольно просто. Этот проект можно запустить из простого примера HelloWorld. Это приложение продемонстрирует, как разработать приложение Android, которое имеет опции меню, выполняет HTTP-вызовы, маршаллизирует данные с использованием JSON и сохраняет состояния в настройках приложения.

Первый шаг — создание точки входа в приложение. Первый экран — это список заданий Гудзона и статус последней сборки в виде красного, синего, желтого шара.

Разработка платформы Android предлагает два варианта разработки пользовательского интерфейса. Либо с помощью кода, либо XML. Код XML может быть изменен во время выполнения приложения Android. В зависимости от вашего уровня комфорта XML легко читается, а плагин eclipse для Android обеспечивает предварительный просмотр. В Android есть несколько «менеджеров макетов», которые предоставляют разработчикам пользовательского интерфейса разнообразные возможности. Самым основным и распространенным по умолчанию является LinearLayout. Возьмите и измените main.xml в android res / layout / main.xml. Добавить представление списка в линейный макет.

Результат должен быть следующим:

 разреш / макет / main.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<ListView android:id="@+id/android:list"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>


</LinearLayout>


 

Нам нужно создать точку входа в основной класс, которую будет использовать платформа Android. Классы действий — это экраны пользовательского интерфейса в приложении Android, аналогично, если приложение имеет несколько экранов для Android, это будет несколько действий. Основным видом деятельности в этом случае является класс SpyHudson, который расширяется от ListActivity.

 SpyHudson.java
public class SpyHudson extends ListActivity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}

 

OnCreate вызывает setContentView (). Если вы заметили, что R.layout.main вызывается и ссылается на ресурс main.xml, это указатель на определения ресурса. Класс R. генерируется автоматически с помощью набора для разработки Android Eclipse. При правильном обновлении XML-файлов в каталоге «res» сгенерированный файл R.java обновляется в eclipse. Рабочее слово правильно, так как если вы допустите ошибки форматирования или ссылки в вашем ресурсе xmls, тогда R.java не будет генерироваться.

Как упоминалось ранее, Hudson поддерживает удаленные вызовы через Xml, JSON и Python. Платформа Android имеет базовую поддержку JSON API. Это делает создание спокойного клиента простым, как выполнение http-вызова и потоковой передачи результатов информации в JSONObjects, которая затем может быть возвращена как ArrayList элементов.

Первый шаг — включить доступ в интернет для приложения Android. Из-за безопасности и разрешений, требуемых платформой Android для приложений, она не включается автоматически. Чтобы включить эту функцию для своего приложения, отредактируйте файл AndroidManifest.xml и добавьте следующую запись перед тегами <application>.

<uses-permission
android:name="android.permission.INTERNET" />

 

 Создайте класс HudsonRestful , который будет принимать указанный URL и анализировать возвращаемую информацию в объектах JSON. Этот класс является скорее вспомогательным вспомогательным классом в контексте этого приложения. Android SDK использует apache http api и обеспечивает его базовую функциональность. Сначала установите HttpClient, выполните HttpGet и прочитайте ответ во входном потоке.

 HudsonRestful.java
private String queryRESTurl(String url) {

// URLConnection connection;

HttpClient httpclient = new DefaultHttpClient();

HttpGet httpget = new HttpGet(url);

HttpResponse response;

try {

response = httpclient.execute(httpget);

Log.i(TAG, "Status:[" + response.getStatusLine().toString() + "]");

HttpEntity entity = response.getEntity();


if (entity != null) {

InputStream instream = entity.getContent();

String result = convertStreamToString(instream);

Log.i(TAG, "Result of converstion: [" + result + "]");

instream.close();

return result;

}

} catch (ClientProtocolException e) {

Log.e("REST", "There was a protocol based error", e);

} catch (IOException e) {

Log.e("REST", "There was an IO Stream related error", e);

}

return null;

}

 

 

 

 

Возможно, вы заметили небольшую разницу в стандартных http-запросах, использующих HTTP-пакет apache. Опять же, вызов метода convertStreamToString () — это не что иное, как стандартная запись BufferedReader для строителя строк, пока он не достигнет конца потока:

 

 HudsonRestful.java (продолжение)
private String convertStreamToString(InputStream is) {

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

StringBuilder sb = new StringBuilder();

String line = null;

try {

while ((line = reader.readLine()) != null) {

sb.append(line + "\n");

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return sb.toString();

}

 

 

Главное — взять возвращаемую строковую информацию и проанализировать ее в JSONObject. Опять же, платформа разработки Android имеет встроенный JSON API. Это делает разработку спокойных клиентов легкой. Это делается следующим образом:

 

 HudsonRestful.java (продолжение)
 

public ArrayList<JSONObject> retrieveJSONArray(String urlString) {

String result = queryRESTurl(urlString);

ArrayList<JSONObject> JOBS = new ArrayList<JSONObject>();

if (result != null) {

try {

JSONObject json = new JSONObject(result);

JSONArray jobsArray = json.getJSONArray("jobs");

for (int a = 0; a < jobsArray.length(); a++) {

JSONObject jobitem = jobsArray.getJSONObject(a);

JOBS.add(jobitem);

}

return JOBS;

} catch (JSONException e) {

Log.e("JSON", "There was an error parsing the JSON", e);

}

}

JSONObject myObject = new JSONObject();

try {

myObject.put("name","No hudson Jobs found");

myObject.put("color", "grey");

JOBS.add(myObject);

} catch (JSONException e1) {

Log.e("JSON", "There was an error creating the JSONObject", e1);

}

return JOBS;

}

 

 

 

 

 

Возвращаясь к основному представлению SpyHudson, мы хотим, чтобы список отображал больше, чем просто текст. Идея состоит в том, чтобы отобразить изображение и текстовый элемент. Способ сделать это — создать графический и текстовый адаптер для списка. Адаптер просматривает переданный ему массив ArrayList JSONObject и устанавливает изображение и текстовое описание для каждого элемента строки в списке.

Первым шагом является создание ресурса макета изображения и текста. В макете ресурсов создайте файл image_text_layout.xml . Подойдет линейный макет, и в этом случае свойство для ориентации будет установлено на горизонтальное, так как это строки создаваемой информации. Затем добавьте два элемента, элемент ImageView и элемент TextView. Результат выглядит следующим образом:

 разреш / макет / image_text_layout.xml
 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content">

<ImageView android:id="@+id/last_build_stat"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/grey"/>

<TextView android:id="@+id/job_text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

</LinearLayout>

 

 

 

Обратите внимание, что в элементе ImageView
android: src ссылается на «@ drawable / grey», это изображение в папке res / drawable / с именем grey.gif.

Создаемый класс адаптера, который будет использовать этот ресурс макета, расширит класс из ArrayAdapter в android.widgets. ArrayAdapter имеет метод getView (), который будет переопределен этой реализацией.

Конструктор класса использует основное действие и список JSONObjects.

 ImageTextListAdapter.java
 

public class ImageTextListAdapter extends ArrayAdapter<JSONObject> {

public ImageTextListAdapter(Activity activity, List<JSONObject> imageAndTexts) {

super(activity, 0, imageAndTexts);

}

 

Переопределите метод getView адаптера Array. Первый раздел будет получать представление от ресурса. Тогда, поскольку это листинг, текущая позиция извлекает JSONObject из переданного массива с помощью вызова метода getItem (position) .

 ImageTextListAdapter.java
 

@Override

public View getView(int position, View convertView, ViewGroup parent) {

Activity activity = (Activity) getContext();

LayoutInflater inflater = activity.getLayoutInflater();

// Inflate the views from XML

View rowView = inflater.inflate(R.layout.image_text_layout, null);

JSONObject jsonImageText = getItem(position);

 

Получение виджета из XML-ресурсов Android, таких как объект ImageView, с помощью вызова findViewById () и вызова идентификатора в XML-ресурсе. Это идентификатор, найденный ранее, как:

< ImageView android: id = «@ + id / last_build_stat»

 Вы можете использовать ссылку findViewById () на любой виджет для представления xml и программно манипулировать представлением во время выполнения.

Следующий шаг, запрос атрибута «color» JSONObject для цветовой строки и установка ресурса представления изображения в соответствующий цвет. Обратите внимание, что «серое» изображение статуса было исключено. Это связано с тем, что в ресурсе макета он уже был объявлен в макете XML и поэтому становится источником изображения по умолчанию.

 ImageTextListAdapter.java (продолжение с getView)
// Load the image and set it on the ImageView

ImageView imageView = (ImageView) rowView.findViewById(R.id.last_build_stat);

String color = "";

try {

color = (String) jsonImageText.get("color");

} catch (JSONException e) {

color = "grey";

}

if (color.equalsIgnoreCase("yellow")) {

imageView.setImageResource(R.drawable.yellow);

} else if(color.equalsIgnoreCase("blue")) {

imageView.setImageResource(R.drawable.blue);

} else if (color.equalsIgnoreCase("red")) {

imageView.setImageResource(R.drawable.red);

}

 

Элемент TextView выполняется таким же образом, но здесь он просто получает атрибут «name» JSONObject и помещает его в текст. Наконец, адаптер списка возвращает rowView обратно в главное представление.

  ImageTextListAdapter.java (продолжение с getView)
 

// Set the text on the TextView

TextView textView = (TextView) rowView.findViewById(R.id.job_text);

try {

textView.setText((String)imageAndText.get("name"));

} catch (JSONException e) {

textView.setText("JSON Exception");

}

return rowView;

}

 

 

Объедините адаптер с основным классом SpyHudson, вернитесь к методу onCreate () и добавьте следующее.

 SpyHudson.java
 

public class SpyHudson extends ListActivity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

spyRest = new HudsonRestful();

String remoteUrl = "http://localhost:8080/hudson/api/json";

ArrayList<JSONObject> jobs = spyRest.retrieveJSONArray(remoteUrl);

setListAdapter(new ImageTextListAdapter(this,jobs));

}

}

 

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

 

Естественно, вам придется указать строку URL на API вашего собственного сервера Hudson. Вы можете прочитать больше об API Hudson на http://wiki.hudson-ci.org/display/HUDSON/Remote+access+API .

Это простое приложение для Android демонстрирует, как создать быстрое простое приложение для Android, которое делает спокойный вызов API HUDSON Rest JSON.