This is an old revision of the document!
Colocviu 2
Model de Subiect
Observații Generale
Pentru rezolvarea subiectelor propuse în cadrul colocviului 2, sunt necesare:
- un cont Github personal, pe care să existe drepturi de citire și de scriere;
- SDK-ul de Android (cu o imagine pentru nivelul de API 16 - Jelly Bean 4.1);
- mediul de dezvoltare integrat Eclipse, împreună cu plugin-ul Android Developer Tools;
- un dispozitiv mobil:
- fizic (bring your own device);
- virtual: Genymotion, AVD.
- fluxbox ca utilitar pentru gestiunea ferestrelor (se alege din interfața de autentificare);
- epiphany pentru navigare Internet.
Este de preferat să nu se depășească memoria disponibilă, întrucât comportamentul acestor mașini este imprevizibil în momentul în care se folosește swap-ul (se blochează, fără posibilitatea de recuperare din eroare).
În situația în care este necesară procesarea codului sursă (în format HTML) al paginii Internet furnizat ca răspuns la cererea transmisă către un serviciu web, se poate folosi biblioteca Jsoup. Integrarea sa în mediul integrat pentru dezvoltare Eclipse Luna SR1a (4.4.1) se face prin plasarea fișierului corespunzător în directorul libs al proiectului. Acesta devine vizibil în momentul în care se accesează operația Refresh din meniul contextual, disponibilă și prin tasta F5. Ulterior, pentru a fi inclus în classpath, este necesar ca din meniul contextual asociat fișierului jsoup-1.8.2.jar (disponibil pe butonul drept al mouse-ului) să se acceseze Build Path → Add to Build Path.
După ce biblioteca a fost integrată în cadrul mediului integrat pentru dezvoltare Eclipse Luna SR1a (4.4.1), aceasta va putea fi vizualizată în secțiunea Referenced Libraries din proiectul corespunzător.
În situația în care este necesară procesarea unui document JSON furnizat ca răspuns la cererea transmisă către un serviciu web, se vor utiliza clasele JSONObject, respectiv JSONArray, din cadrul SDK-ului Android. Pentru vizualizare, se poate folosi utilitarul JSON Formatter & Validator, prin care structura documentului JSON poate fi inspectată cu ușurință.
Rezolvări
Proiectul Eclipse corespunzător aplicației Android ce conține rezolvările complete ale cerințelor colocviului este disponibil pe contul de Github al disciplinei.
1. Se accesează Github și se realizează autentificarea în contul personal, prin intermediul butonului Sign in.
Se creează o zonă de lucru corespunzătoare unui proiect prin intermediului butonului New Repository.
Configurarea depozitului la distanță presupune specificarea:
- unei denumiri;
- unei descrieri (opțional);
- tipului de director (public sau privat - doar contra cost!!!);
- modului de inițializare:
- local, prin
git init; - la distanță, prin
git clone- depozitul la distanță nu trebuie să fie vid, în această situațoe
- unui fișier
README(opțional); - extensiilor ignorate (corespunzătoare limbajului de programare folosit, în cazul de față - Android) - incluse în fișierul
.gitignore; - tipului de licență sub care este publicat codul sursă.
2. Prin intermediul comenzii git clone se poate descărca întregul conținut în directorul curent (de pe discul local), inclusiv istoricul complet al versiunilor anterioare (care poate fi ulterior reconstituit după această copie, în cazul coruperii informațiilor stocate pe serverul la distanță).
student@pdsd2015:~$ git clone https://www.github.com/perfectstudent/PracticalTest02
3. Se urmăresc indicațiile disponibile în secțiunea Crearea unei aplicații Android în Eclipse Luna SR1a (4.4.1).
4. Pentru implementarea interfeței grafice, se vor defini controalele care asigură interacțiunea cu utilizatorul pentru fiecare dintre componentele aplicației Android:
- serverul
- un câmp text pentru specificarea portului pe care va accepta conexiuni de la clienți;
- un buton pentru lansarea în execuție;
- clientul
- câmpuri text pentru precizarea parametrilor de conexiune la server:
- adresa Internet (se va folosi
localhostsau127.0.0.1); - port;
- elemente grafice pentru indicarea informațiilor solicitate:
- un câmp text pentru oraș;
- o listă populată cu datele meteorologice care se doresc a fi furnizate (temperature, wind_speed, condition, pressure, humidity, all); ca alternativă, se poate folosi tot un câmp text, cu restricția ca valorile introduse să facă parte din mulțimea acceptată;
- un buton pentru trimiterea cererii și primirea răspunsului, condiționată de completarea anterioară a tuturor celorlalte informații.
- activity_practical_test02_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="ro.pub.cs.systems.pdsd.practicaltest02.graphicuserinterface.PracticalTest02MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="25sp" android:textStyle="bold" android:text="@string/server" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:baselineAligned="false"> <ScrollView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"> <EditText android:id="@+id/server_port_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/server_port" /> </ScrollView> <ScrollView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"> <Button android:id="@+id/connect_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/connect" /> </ScrollView> </LinearLayout> <Space android:layout_width="wrap_content" android:layout_height="10dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="25sp" android:textStyle="bold" android:text="@string/client" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:baselineAligned="false"> <ScrollView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"> <EditText android:id="@+id/client_address_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/client_address" /> </ScrollView> <ScrollView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"> <EditText android:id="@+id/client_port_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/client_port" /> </ScrollView> </LinearLayout> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:rowCount="2" android:columnCount="2"> <EditText android:id="@+id/city_edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="5" android:hint="@string/city" android:layout_row="0" android:layout_column="0" /> <Spinner android:id="@+id/information_type_spinner" android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/information_types" android:layout_row="1" android:layout_column="0" /> <Button android:id="@+id/get_weather_forecast_button" android:layout_width="100dp" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/get_weather_forecast" android:layout_row="0" android:layout_rowSpan="2" android:layout_column="1" /> </GridLayout> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/weather_forecast_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="false" android:maxLines="10" /> </ScrollView> </LinearLayout>
android.permission.INTERNET), specificată explicit în fișierul AndroidManifest.xml:- AndroidManifest.xml
<manifest ...> <!-- other elements --> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
- firul de execuție al interfeței grafice; un control grafic nu va putea fi modificat decât din contextul acestui fir de execuție (în acest sens, se va utiliza metoda
post()a elementului respectiv pentru interacțiunea cu utilizatorul sau un obiect de tipHandler); - firul de execuție pentru comunicație, necesar astfel încât operațiile care necesită acces la rețea să nu blocheze interacțiunea cu utilizatorul, afectând experiența acestuia; în practică, se va defini un fir de execuție pentru server (pe care sunt acceptate conexiunile de la clienți) și câte un fir de execuție pentru fiecare comunicație dintre client și server, astfel încât interacțiunea dintre acestea să nu influențeze reponsivitatea serverului și nici comunicația cu ceilalți clienți.
5.
6.
7. Pentru încărcarea codului în contextul depozitului din cadrul contului Github personal:
- se transferă modificările din zona de lucru în zona de lucru în zona de așteptare prin intermediul comenzii
git add, indicându-se și fișierele respective (pot fi folosite șabloane pentru a desemna mai multe fișiere); - se consemnează modificările din zona de așteptare în directorul Git prin intermediul comenzii
git commit -m, precizându-se și un mesaj sugestiv: - se încarcă modificările la distanță, prin intermediul comenzii
git push, care primește ca parametrii:- sursa (prin eticheta
originse indică depozitul de unde au fost descărcat conținutul); - destinația: ramificația curentă (implicit, aceasta poartă denumirea
master).
student@pdsd2015:~/PracticalTest02$ git add * student@pdsd2015:~/PracticalTest02$ git commit -m "finished tasks for PracticalTest02" student@pdsd2015:~/PracticalTest02$ git push origin master
În cazul în care este necesar, vor fi configurați parametrii necesari operației de consemnare (numele de utilizator și adresa de poștă electronică):
student@pdsd2015:~/PracticalTest02$ git config --global user.name "Perfect Student" student@pdsd2015:~/PracticalTest02$ git config --global user.email perfectstudent@cs.pub.ro
8.
9.
10.
