MójDroid.pl

#4 Twórz aplikacje na Androida z Mojdroid.pl - Struktura aplikacji oraz nasze pierwsze Hello World!

2012-09-15
|
Damian P.

Czas na napisanie swojej pierwszej aplikacji, tak zwanego "Hello World" . W tym poradniku dowiecie się jak to zrobić z pomocą Eclipse, jakie są typy edytorów w naszym IDE, do czego służy AndroidManifest w programach, gdzie co tworzyć i dodawać oraz wiele więcej... Bez zbędnego gadania, zaczynamy, bo podpunktów jest sporo!

1. Tworzymy projekt

Uruchamiamy Eclipse, po czym w naszym doku Package Explorer lub menu narzędziowym File wybieramy pozycję New i Android Application Project. Jeżeli wszystko dobrze zrobiliście, zobaczycie mniej więcej takie okienko: Jest to standardowy kreator projektu aplikacji dla Androida. Niestety, zmienia się on bardzo często i możliwe, że wkrótce będzie on kompletnie inaczej wyglądał. No ale na to nic nie poradzę, tutaj tworzę na aktualnie dostępnym. Po co nam ten cały kreator? Jak każdy inny element tego typu, tak i ten służy on nam do łatwego wprowadzania podstawowych danych, tutaj wymaganych przez system Android. Jak pewnie już zauważyliście, jest to nazwa aplikacji, projektu (to dla Eclipse), paczki (dla pliku apk i unikalnego identyfikatora w markecie), wersja systemu, pod którą SDK ma kompilować program, oraz minimalna wymagana wersja systemu przez program. Poniższe checkboxy natomiast służą do tworzenia ikony w kolejnych krokach (odznaczcie to najlepiej), oznaczenia projektu jako biblioteka (odznaczcie) oraz do wskazania niestandardowej lokalizacji projektu na dysku (zostawcie zaznaczone). Pola wypełniamy jak chcemy, wpisując nazwę aplikacji w "Application Name" (np Moja pierwsza aplikacja), nazwę projektu w "Project Name" oraz nazwę paczki w "Package Name". Ta ostatnia powinna stosować się do ogólnej konwencji nazywania paczek w języku Java, to znaczy tworzyć hierarchię, gdzie każdy poziom jest oddzielony kropką. Ważne jest również to, aby ta nazwa była unikalna - jeżeli użyjemy zajętej już nazwy, market nam aplikacji nie przyjmie. Nazwa paczki rozpoczyna się od głównej domeny, zazwyczaj nazwy organizacji czy autora i zapisuje w odwrotnej kolejności (np eclipse.org nazywa swoje paczki org.eclipse). Kolejne miejsca oznaczają subdomeny. Wersję systemu powinniśmy wybrać starannie, ale w razie pomyłki później możemy to zmienić. Pierwsze pole to wersja Androida, pod którą chcemy kierować aplikację. Polecam wybranie czegoś aktualnego, jak na przykład 4.1 lub 4.0.  Większe znaczenie ma niższe pole, czyli minimalna wymagana wersja oprogramowania. Jest to informacja dla marketu oraz Androida, od której wersji program ma działać. Powinniśmy wybrać coś pomiędzy 2.0 a 2.3, aby program był obecny na większości smartfonów. Klikamy dalej. Pojawi się okienko o tworzenie pierwszego Activity. Jest to opcjonalna funkcja i nic nie musimy tworzyć, ale dla łatwiejszej pracy zaznaczmy jednak pierwszą opcję - "BlankActivity" - i przejdźmy dalej. Kolejny krok to konfigurowanie swojego pierwszego Activity, jeżeli zaznaczyliśmy wcześniej tworzenie go na starcie. Wpisujemy tutaj co chcemy, ja polecam jednak zachowanie jakiejkolwiek konwencji (nawet własniej) w nazwach, co by to później się nie pogubić. Przykładowo, główne Activity niech nazywa się View_Main lub ViewMain (View - bo będzie mieć layout i inne widoki), a layout dla niego view_main (pisane z małych literek). Dzięki temu chcąc wprowadzić zmiany nie będziemy musieli przeklikywać się przez tuzin plików, aby dotrzeć do tego jednego. "Navigation Type" i "Hierarchical Parent" pozostawiamy puste, "Title"  powinno nazywać się tak samo jak "Activity Name". Klikamy finish, projekt się tworzy i bam - widzimy swój layout dla programu.

2. Edytory w Eclipse IDE i Android SDK

Jak pewnie zauważyliście, Eclipse posiada graficzny edytor layoutów XML (w takim są formacie). Jest on całkiem przydatny, bo większości elementów Views nie musimy tworzyć ręcznie wpisując w edytorze tekstowym. Wystarczy jedynie z lewego panelu przeciągnąć coś do layoutu i element zostaje stworzony na wybranym miejscu. Proste i przyjemne. Ale uwaga! Nie wierzcie mu do końca, jest masa przypadków, gdzie on po prostu jest bezużyteczny. Traktujcie ten edytor jako pomocniczy, a nie podstawowy. Naszą podstawą oczywiście będzie wersja tekstowa. Dostaniecie się do niej klikając ten przycisk w rogu: Wtedy widzimy czysty kod, w którym możemy ręcznie i dowolnie ustalać atrybuty. Podobnie będzie z innymi plikami, używamy edytora tekstowego zamiast graficznego.

3. Co, gdzie i jak - architektura aplikacji

Android, jak sami wiecie, działa na wielu urządzeniach - od smartfonów, przez tablety, a na całych komputerach kończąc. Oznacza to, że struktura programu będzie bardzo podzielona na części, by zapewnić wsparcie niezależnie od zaplecza sprzętowego. I nie jest to wcale wada, bo dzięki przemyślanej konstrukcji za bardzo nie musimy martwić się o to, jak program będzie się zachowywał się (i wyglądał) na różnym sprzęcie. Główny rywal Androida - iOS - takiego dodatku nie miał, co w końcu doprowadziło do tragedii na iPhone 5, gdzie na dole i górze ekranu widzimy czarne pasy, a w pierwszej fazie wprowadzania iPada widzieliśmy małe, rozciągnięte okienko na cały obszar. My z góry ustalony mamy inny porządek. Struktura aplikacji na Androida prezentuje się następująco: Idąc po kolei po folderach i plikach:
  • src - pliki .java programu, gdzie znajduje się cała logika aplikacji. To tutaj dodajemy klasy, definiujemy poszczególne Activity, Adaptery i tak dalej. Całość jest gromadzona w paczkach, które są oczywiście jednocześnie nazwą .apk w katalogu /data/app w Androidzie (jednak to nie jest przymus, czasem system dopisuje sam coś do nazwy a i tak program działa). Jak widzicie, posiadamy jedną klasę o nazwie View_Main, która została stworzona automatycznie w kreatorze.
  • gen - pliki generowane przez kompilator (i pre-kompilator) do poprawnego działania aplikacji. Nic ciekawego dla nas tam nie znajdziemy, lepiej nie ruszajcie tego folderu.
  • assets - jeden z folderów z zasobami dla naszego programu. Tutaj dodajemy pliki dowolnego formatu, które później chcemy użyć w aplikacji. Uwaga! Android nie generuje tutaj id dla każdego elementu, chcąc użyć jakiegoś pliku z tego folderu musimy podać jego ścieżkę!
  • bin - pliki binarne, nic wartego uwagi - podobnie jak gen
  • libs - tutaj wklejamy ewentualne zewnętrzne biblioteki do programów. We wcześniejszych wersjach SDK/ADP ten folder nazywał się lib, co obecnie może powodować błędy i zakłopotanie, jeżeli stosujemy się do jakiegoś starszego poradnika. Jak widzicie, mamy tam android-support-v4.jar, czyli bibliotekę znaną szerzej jako compability library. Po co nam ona? W skrócie umożliwia korzystanie z nowych API z Androida 4.0 na starszych urządzeniach. Dzięki temu możemy pisać jeden kod (mniej więcej), a i tak będzie on działał na starszych wersjach systemu. Uwaga! Niektóre  biblioteki należy dodawać do projektu przez Properties->Android->Add lub Properties->Java Build Path->Libraries->Add JARs, klikając najpierw prawym przyciskiem myszy na projekt! Próbujcie obu sposobów, jeżeli któryś nie działa.
  • res - główny folder z zasobami dla programu. Działa podobnie do assets, z tą różnicą, że generowane są identyfikatory do pliku R.java, przez co w programie nie musimy znać jego lokalizacji a jedynie nazwę. To tutaj dbamy również o wygląd aplikacji na różnych urządzeniach - wystarczy dodać odpowiednie foldery, skopiować layout który chcemy nieco zmienić, wkleić do wybranego przedziału i gotowe. Wszystko samo zadziała. Tłumacząc kolejne podfoldery: - w drawable-xxxx dodajemy pliki graficzne w różnych rozdzielczościach (xhdpi - bardzo wysoka, hdpi - wysoka, mdpi - średnia , ldpi - niska rozdzielczość) - w drawable pliki xml z generowanymi kształtami (np tła z ramką) - w layout-xxxx szablony wyglądu w różnych wielkościach (np dla tabletów i telefonów) - w menu ustawienia przycisku menu (lub actionbara) - w values różne ciągi znaków i ustawienia.Uwaga! Android musi rozpoznawać formaty tych plików, aby mogły one się w tym miejscu znaleźć! 
  • AndroidManifest.xml - konfiguracja aplikacji, o tym za chwilę.
  • Oraz różne ustawienia dla Eclipse
Tych folderów jest nieco więcej dostępnych, więcej w dokumentacji Androida. Podstawowe póki co nam wystarczą. Jest tego sporo i trzeba to wykuć na pamięć, ale pisząc aplikacje sami zobaczycie, że ma to sens i jest bardzo proste. Przejdźmy jednak dalej, do AndroidManifestu.

4. AndroidManifest.xml 

Uruchomcie plik AndroidManifest. Przy pierwszym razie zauważycie znowu graficzny edytor pliku, wyłączcie go i przejdźcie do tekstowego. W nim znowu zobaczycie coś podobnego do tego kodu:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.moja.pierwsza.aplikacja"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="5"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".View_Main"
            android:label="@string/title_activity_view__main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Jest to nic innego jak konfiguracja aplikacji. Co w niej powinno być? Deklaracja każdego Activity, używane uprawnienia, wersje SDK, wersja aplikacji, intent-filtery, nazwa programu i takie tam. Zacznijmy od deklaracji głównego Activity, w tym wypadku nazwanego "View_Main". Jak widzicie dodany jest do niego intent-filter, który posiada wartości z kategorii LAUNCHER i akcji MAIN. Po poprzednich poradnikach już wiecie, że intent-filter reaguje na niektóre zdarzenia w systemie, tutaj akurat pokazuje nam nasze Actvity na liście dostępnych programów w Launcherze. Tak więc, gdy wybrana zostanie nasza aplikacja, to od razu uruchomi się Activity kryjące się pod klasą ".View_Main". Proste. Jeżeli chcemy dodać więcej ikonek do listy aplikacji (jak np. Facebook), powinniśmy ten kawałek skopiować (od <activity) i użyć innych wartości. Deklarując inne Activity (bez ikony) nie musimy używać dokładnie tego kodu, wystarczy wkleić coś takiego:
<activity android:name=".View_Welcome" />
I normalnie używać dodanej klasy w programie. Jeżeli coś takie pominiemy, Android wyrzuci błąd o niezarejestrowanym Activity. Może się zdarzyć, że w programie będziemy potrzebować uprawnień np. do dostępu do internetu. Wtedy gdzieś na początku pliku, najlepiej po <uses-sdk>, dodajemy linię podobną do tej:
<uses-permission android:name="android.permission.INTERNET" />
Pozwala ona oczywiście korzystać z wybranych zasobów, informując jednocześnie usera o takich funkcjach przy instalacji. Lista dostępnych praw oraz więcej informacji znajdziecie tutaj oraz tutaj. PS. Zauważyliście linię @string/app_name albo @drawable/ic_launcher? To przykład wykorzystania zasobów z folderu res w plikach XML :)

5. Klasy do pracy!

Na (prawie) sam koniec przejdźmy do folderu src, gdzie jak wiecie jest logika naszej aplikacji, i wybierzcie swoje domyślne Activity. W tym pliku javazobaczycie mniej więcej taki kod:
package com.example.moja.pierwsza.aplikacja;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class View_Main extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view__main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_view__main, menu);
        return true;
    }
}
Są to działania, jakie aplikacja wykonuje. Nie są one zbyt rozbudowane, ale w końcu nie takie mają być przy samym tworzeniu projektu. Z poprzednich wpisów wiecie już czym jest funkcja OnCreate, a jeżeli nie kojarzycie za bardzo, to przypomnę wam, że kod w niej wykonuje się od razu przy uruchomieniu Activity, czy jeszcze dokładniej dokładniej - obiektu klasy (bo onCreate możemy używać również w innych elementach systemu, nie tylko w Activity).  W tym wypadku ustawiany jest jedynie layout z folderu res/layout/ (R. to wszystkie wygenerowane ID, layout zasób w res, a ostatnia część to nazwa pliku). onCreateOptionsMenu natomiast służy do generowania menu z zasobu res/menu. Zostawmy na chwilę to wszytko tak jak jest i uruchommy aplikację.

5a. Uruchamianie aplikacji na urządzeniu

Jak uruchomić aplikację? Najprościej jest wybrać odpowiedni przycisk z Eclipse IDE. Jest to to zielone koło ze znaczkiem play: Po kliknięciu zobaczymy kilka okienek, gdzie klikamy odpowiednio "Android Application" i tym podobne. Przechodząc dalej IDE może nas pytać o zapis plików, co potwierdzamy, oraz o sprzęt. Tutaj dobrze jest podłączyć własnego smartfona z włączonym Debugowaniem USB (Ustawienia->Aplikacje->Debuguj), a jeżeli takiego nie posiadamy, to wymagane będzie stworzenie wirtualnej maszyny AVD. To z kolei ten przycisk: Klikamy New i postępujemy wg wskazówek, bardzo prostych zresztą. Po wszystkim na urządzeniu zobaczymy ruch, a w ostatecznym efekcie nasz program :)

5b. Co by tu zmienić...

Zróbmy coś prostego i zobaczmy efekty - na przykład zmieńmy napis Hello world na inny, dowolny. Najpierw musimy przejść do naszego layoutu z tekstem. Otwórzcie edytor tekstowy, znajdźcie element TextView w ViewGroup RelativeLayout i dodajcie do atrybutów pole id z dowolną nazwą, tak aby wyglądało to jak poniżej:
    <TextView
        android:id="@+id/tvTest"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world"
        tools:context=".View_Main" />
Pamiętajcie o dobrych praktykach, skoro jest to TextView to nazwę elementu stwórzcie tak, abyście wiedzieli, że to on. U mnie jest to tvTest (tv od TextView). Zapisz XML i przejdź do klasy z Activity (folder src) - w pliku View_Main funkcję OnCreatezmień tak:
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view__main);

        TextView tvTest1 = (TextView) findViewById(R.id.tvTest);
        tvTest1.setText("Jakiś tekst");
    }
Co zrobiliśmy? Jeżeli wcześniej programowałeś, to doskonale wiesz co - z definiowaliśmy zmienną typu TextView o nazwie tvTest1, przypisaliśmy do niej View (rzutując na typ TextView) o id tvTest (to z pliku XML), po czym ustawiliśmy na niej swój tekst. Po wszystkim uruchamiamy i boom, jest efekt :) Prosty, ale zawsze coś. Na dziś to tyle. Sporo się nauczyliśmy, czas więc odpocząć i przygotować się na więcej - jutro będziemy już reagować na kliknięcia! Uff...