Збереження конфігурації запуску додатку Конфігурація запуску включає настройки компіляції і відладки додатків. Вони дозволяють управляти наступними функціями:
- вибір проекту і Активності для запуску;
- управління віртуальним пристроєм і емулятором;
- настройки введення і висновку (включаючи параметри консолі за замовчуванням).
Можна використовувати різні конфігурації для запуску і відладки. Щоб зберегти конфігурацію запуску для додатку Android зробіть наступне.
1. В меню Eclipse виконаєте команду Run Run Configurations або Debug
Configurations.
2. В списку типів проектів виберіть пункт Android Application, клацніть
на ньому правою кнопкою миші і виберіть New.
3. Вкажіть назву для поточної конфігурації. Ви можете створювати
декілька конфігурацій для кожного проекту. Вибирайте зрозумілі назви, щоб ідентифікувати той або інший набір параметрів.
4. Тепер можна приступати до настройки запуску додатку. Перша вкладка (Android) дозволяє вибирати проект для компіляції, а також Активність, яка запускатиметься під час компіляції (або відладки) додатки. На рисунку 9.2 показані настройки раніше створеного проекту.
Рисунок 9.2 – Настройки ранцішествореного проекту
5. На вкладці Target, яка показана на рисунку 9.3, можна вибрати віртуальний пристрій за умовчанням, на якому запускатиметься додаток. Також можна використовувати параметр Manual, при цьому при кожній компіляції/відладці потрібно вибирати пристрій або AVD. На цій вкладці можна змінити мережні настройки емулятора очистити призначені для користувача дані або відключити анімацію, яка програється під час запуску віртуального пристрою.
В полі Command Line Options при необхідності можна вказати додаткові
параметри запуску емулятора.
6. На вкладці Common є деякі додаткові настройки.
7. Натискуйте кнопку Apply. Конфігурація для запуску додатку зберігається
Рисунок 9.3 – Вкладка Target
Компіляція і відладка додатків
Ви створили перший проект і зберегли конфігурації компіляції і відладки. Перш ніж робити щось ще, необхідно перевірити правильність установки і настройки середовища розробки. Для цього спробуйте відкомпілювати і відладити проект «Hello World!».
В меню Run виберіть пункт Run або Debug - для запуску додатку відповідно до збережених настройок або Run Configurations, або Debug Configurations - для вибору конкретної збереженої конфігурації.
Якщо використовується плагін ADT, компіляція або відладка додатку відбуватиметься таким чином:
- поточний проект скомпілюється у виконуваний файл платформи Android з розширенням .dex;
- виконуваний файл і зовнішні ресурси упакуються у файл пакету Android з розширенням .apk;
- запуститься вибраний віртуальний пристрій (якщо ви вибрали AVD і він в даний момент не запущений);
- додаток встановиться на цільовий пристрій;
- додаток запуститься.
Для відладки використовується відладчик Eclipse, в ньому можна задавати крапки, зупинки для відладки коду програм.
Якщо все виконано правильно, ви побачите нову Активність, запущену в емуляторі (рисунок 9.4).
Рисунок 9.4 – Вікно емулятора
Контрольні питання:
1. Що таке Android?
2. Що таке Dalvik?
3. Які пакети необхідні перед початком роботи?
4. Як відбувається створення нового проекту Android?
5. Як відбувається збереження конфігурації запуску додатку?
6.Як відбувається компіляція і відладка додатків?
Література:
1. Хашими С., Коматинени С., Маклин Д. Разработка приложений для Аndroid.- СПб.: Питер, 2011. – 736 с.: ил., стор. 50-83.
2. Майер Р.Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с., стор 44-83.
Лабораторна робота № 9
Тема: Операційна система Android. Розробка додатків
Мета:Освоїти навички роботи по розробці додатків для Android .
Завдання: Створити власний додаток для операційної системи Android
8. Обладнання та матеріали: ПК, операційна система Android, методичні вказівки до лабораторних робіт.
Хід роботи:
1.Ознайомитись з теоретичними відомостями.
2. Запустити емулятор Dalvik.
1. Скачати та встановити необхідні додатки.
2. Виконати створеня проекту.
3. Зберегти конфігурацію запуску додатку.
4. Відкомпілювати та відлагодити додаток.
5. Оформити та захистити звіт лабораторної роботи.
Теоретичні відомості
Структура проекту
В процесі роботи використовуються наступні каталоги: gen, resи src. В теці gen знаходяться файли, які генеруються автоматично при збірці проекту.
Уручну їх міняти не можна. Тека res призначена для зберігання ресурсів, таких як картинки, тексти (у тому числі переклади), значення по-умолчанию, макети (layouts). Src - це тека в якій відбуватиметься основна частина роботи, бо тут зберігаються файли з початковими текстами нашої програми - перші рядки.
Як тільки створюється Activity (екран додатку), викликається метод onCreate(). IDE заповнила його 2 рядками:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Метод setContentView (рівносильно this.setContentView) встановлює xml-макет для поточного екрану. Далі xml-макети називатимемо «layout», а екрани - «Activity».
Як приклад розробки створюється просту гра «Хрестики-нулі» з одним екраном..
Для цього додатку ідеально підійде TableLayout. Id можна привласнити будь-якому ресурсу. В даному випадку, TableLayout привласнений id = main_l. За допомогою методу findViewById() можна отримати доступ до вигляду:
Private ТableLayout layout; // це властивість класу KrestikinolikiActivity
Public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (TableLayout) findViewById(R.id.main_1);
buildGameField();
}
Тепер необхідно реалізувати метод buildGameField(). Для цього вимагається згенерувати поле у вигляді матриці. Цим займатиметься клас Game. Спочатку потрібно створити клас Square для осередків і клас Player, об'єкти якого заповнюватимуть ці осередки.
Square.java
package com.example;
public class Square
{private Player player = null;
public void fill (Player player) {
this. player = player; }
}
public Boolean isFilled()
{ if (player!= null)
{return true;}
return false;}
public Player get Player() {
return player;
}
}
Player.java
package com.example;
public class Player {
private String name;
public Player(String name) {
this.name = name;
}
public CharSequence getName() {
return (CharSequence) name;
}
}
Всі класи додатку занходяться в папці src. Game.java
package com.example;
public class Game {
/**
* поле
*/
private Square[][] field;
/**
* Конструктор
*/
public Game() {
field = new Square[3][3];
squareCount = 0;
// заполнение поля
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j] = new Square();
squareCount++;
}
}
}
public Square[][] getField() {
return field;
}
}
Ініціалізація в конструкторі KrestikinolikiActivity. public KrestikinolikiActivity() {
game = new Game();
game.start(); // будет реализован позже
}
Метод buildGameField() класу KrestikinolikiActivity. Він динамічно додає рядки та стовпчики в таблицю (ігровоі поле):
private Button[][] buttons = new Button[3][3];
//(....)
private void buildGameField() {
Square[][] field = game.getField();
for (int i = 0, lenI = field.length; i < lenI; i++ ) {
TableRow row = new TableRow(this); // создание строки таблицы
for (int j = 0, lenJ = field[i].length; j < lenJ; j++) {
Button button = new Button(this);
buttons[i][j] = button;
button.setOnClickListener(new Listener(i, j)); // установка слушателя, реагирующего на клик по кнопке
row.addView(button, new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT)); // добавление кнопки в строку таблицы
button.setWidth(107);
button.setHeight(107);
}
layout.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,
TableLayout.LayoutParams.WRAP_CONTENT)); // добавление строки в таблицу
}
}
В рядку 8 створюється об'єкт, реалізовуючий інтерфейс View.OnClickListener. Створимо вкладений клас Listener. Він буде видний тільки з KrestikinolikiActivity.
public class Listener implements View.OnClickListener {
private int x = 0;
private int y = 0;
public Listener(int x, int y) {
this.x = x;
this.y = y;
}
public void onClick(View view) {
Button button = (Button) view;
}
}
Залишилось реалізувати логіку гри. public class Game {
/**
* игроки
*/
private Player[] players;
/** * поле
*/
private Square[][] field;
/** * начата ли игра?
*/
private boolean started;
/** * текущий игрок
*/
private Player activePlayer;
/** * Считает колличество заполненных ячеек
*/
private int filled;
/** * Всего ячеек
*/
private int squareCount;
/** * Конструктор
*/
public Game() {
field = new Square[3][3];
squareCount = 0;
// заполнение поля
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j] = new Square();
squareCount++;
}
}
players = new Player[2];
started = false;
activePlayer = null;
filled = 0;
}
public void start() {
resetPlayers();
started = true;
}
private void resetPlayers() {
players[0] = new Player("X");
players[1] = new Player("O");
setCurrentActivePlayer(players[0]);
}
public Square[][] getField() {
return field;
}
private void setCurrentActivePlayer(Player player) {
activePlayer = player;
}
public boolean makeTurn(int x, int y) {
if (field[x][y].isFilled()) {
return false;
}
field[x][y].fill(getCurrentActivePlayer());
filled++;
switchPlayers();
return true;
}
private void switchPlayers() {
activePlayer = (activePlayer == players[0]) ? players[1] : players[0];
}
public Player getCurrentActivePlayer() {
return activePlayer;
}
public boolean isFieldFilled() {
return squareCount == filled;
}
public void reset() {
resetField();
resetPlayers();
}
private void resetField() {
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j].fill(null);
}
}
filled = 0;
}
}
В хрестики-нулі виграє той, хто вистроє X або О в лінію завдовжки, рівній довжині поля по-вертикали, або по-горизонтали, або по-диагонали. В цьому випадку добре підійде паттерн Chain Responsobility. Визначимо інтерфейс
расkage com.example;
public interface WinnerCheckerInterface {
public Player checkWinner();
}
Оскільки Game наділює обов'язком виявляти переможця, він реалізує цей інтерфейс. Настав час створити віртуальних «лайнсменов», кожний з яких перевірятиме свою сторону. Всі вони реалізує інтерфейс WinnerCheckerInterface.
WinnerCheckerHorizontal.java
package com.example;
public class WinnerCheckerHorizontal implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerHorizontal(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
for (int i = 0, len = field.length; i < len; i++) {
lastPlayer = null;
int successCounter = 1;
for (int j = 0, len2 = field[i].length; j < len2; j++) {
currPlayer = field[i][j].getPlayer();
if (currPlayer == lastPlayer && (currPlayer != null && lastPlayer !=null)) {
successCounter++;
if (successCounter == len2) {
return currPlayer;
}
}
lastPlayer = currPlayer;
}
}
return null;
}
}
WinnerCheckerVertical.java
package com.example;
public class WinnerCheckerVertical implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerVertical (Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
for (int i = 0, len = field.length; i < len; i++) {
lastPlayer = null;
int successCounter = 1;
for (int j = 0, len2 = field[i].length; j < len2; j++) {
currPlayer = field[j][i].getPlayer();
if (currPlayer == lastPlayer && (currPlayer != null && lastPlayer !=null)) {
successCounter++;
if (successCounter == len2) {
return currPlayer;
}
}
lastPlayer = currPlayer;
}
}
return null;
}
}
WinnerCheckerDiagonalLeft.java
package com.example;
public class WinnerCheckerDiagonalLeft implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerDiagonalLeft(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
int successCounter = 1;
for (int i = 0, len = field.length; i < len; i++) {
currPlayer = field[i][i].getPlayer();
if (currPlayer != null) {
if (lastPlayer == currPlayer) {
successCounter++;
if (successCounter == len) {
return currPlayer;
}
}
}
lastPlayer = currPlayer;
}
return null;
}
}
WinnerCheckerDiagonalRight.java
package com.example;
public class WinnerCheckerDiagonalRight implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerDiagonalRight(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
int successCounter = 1;
for (int i = 0, len = field.length; i < len; i++) {
currPlayer = field[i][len - (i + 1)].getPlayer();
if (currPlayer != null) {
if (lastPlayer == currPlayer) {
successCounter++;
if (successCounter == len) {
return currPlayer;
}
}
}
lastPlayer = currPlayer;
}
return null;
}
}
Проинициализируем их в конструкторе Game: //(....)
/**
* "Судьи" =). После каждого хода они будут проверять, нет ли победителя
*/
private WinnerCheckerInterface[] winnerCheckers;
//(....)
public Game() {
//(....)
winnerCheckers = new WinnerCheckerInterface[4];
winnerCheckers[0] = new WinnerCheckerHorizontal(this);
winnerCheckers[1] = new WinnerCheckerVertical(this);
winnerCheckers[2] = new WinnerCheckerDiagonalLeft(this);
winnerCheckers[3] = new WinnerCheckerDiagonalRight(this);
//(....)
}
Реализация checkWinner(): public Player checkWinner() {
for (WinnerCheckerInterface winChecker : winnerCheckers) {
Player winner = winChecker.checkWinner();
if (winner != null) {
return winner;
}
}
return null;
}
Победителя проверяем после каждого хода. Добавим кода в метод onClick() класса Listener
public void onClick(View view) {
Button button = (Button) view;
Game g = game;
Player player = g.getCurrentActivePlayer();
if (makeTurn(x, y)) {
button.setText(player.getName());
}
Player winner = g.checkWinner();
if (winner != null) {
gameOver(winner);
}
if (g.isFieldFilled()) { // в случае, если поле заполнено
gameOver();
}
}
Метод gameOver() реализован в 2-х вариантах: private void gameOver(Player player) {
CharSequence text = "Player \"" + player.getName() + "\" won!";
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
game.reset();
refresh();
}
private void gameOver() {
CharSequence text = "Draw";
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
game.reset();
refresh();
}
Для Java, gameOver(Player player) і gameOver() - різні методи. Скориставшися Builder'ом Toast.makeText, можна швидко створити і показати повідомлення. refresh() обновляє стан поля:
private void refresh() {
Square[][] field = game.getField();
for (int i = 0, len = field.length; i < len; i++) {
for (int j = 0, len2 = field[i].length; j < len2; j++) {
if (field[i][j].getPlayer() == null) {
buttons[i][j].setText("");
} else {
buttons[i][j].setText(field[i][j].getPlayer().getName());
}
}
}
}
Контрольні питання:
1. Яка структура проекту?
2. Що таке активність?
3. Які пакети необхідні перед початком роботи?
4. Що необхідно для створення власного додатку?
Література:
1. Хашими С., Коматинени С., Маклин Д. Разработка приложений для Аndroid.- СПб.: Питер, 2011. – 736 с.: ил., стор. 83 - 203.
2. Майер Р.Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с., стор 85-128.
|