android.os class
Za pomocą klasy AsyncTask możemy operacje asynchroniczne wykonywać w tle. Tworzony obiekt AsyncTask, dziedziczy po klasie AsyncTask. Za pomocą klasy AsyncTask możemy w tle, aktualizować bazę danych lub pobierać dane z serwera.
Klasę AsyncTask dodajemy wewnątrz aktywności, w której chcemy jej używać.
Ta klasa została wycofana na poziomie interfejsu API 30.
Zamiast tego użyj standardowych narzędzi do współbieżności java.util.concurrent
lub zamiast tego narzędzia współbieżności Kotlin.
Klasa AsyncTask definiuje metody:
onPreExecute() // metoda opcjonalna jest wywoływana przed rozpoczęciem kodu metody
// doInBackground() działającej w tle
doInBackground() // metoda musi być zaimplementowana, kod wykonywany w tle
onProgressUpdate() // metoda opcjonalna publikuje postępy kodu metody
// doInBackground() działającej w tle
onPostExecute() // metoda opcjonalna wywoływana po zakończeniu kodu metody
// doInBackground() działającej w tle
Klasę AsyncTask definiujemy po przez podanie trzech parametrów:
Params - typ obiektu używanego do przekazania parametrów do metody doInBackground()
Progress - typ obiektu stosowanego do przekazywania informacji o postępach wykonywanego kodu
Results - typ wyniku zwracanego przez wykonany kod w metodzie doInBackground() odbierany w onPostExecute()
przykład:
private class MojaKlasa extends AsyncTask<Integer, Progress, Boolean> {
// doInBackground(Integer... kod) onPostExecute(Boolean result)
private class MojaKlasa extends AsyncTask<String, Void, String> {
// doInBackground(String... adres) onPostExecute(String result)
Parametr nie używany określamy jako Void.
Postać AsyncTask:
private class MojaAsyncTask extends AsyncTask<Params, Progress, Result>
protected void onPreExecute() {
// Kod wykonany przed rozpoczęciem zadania
}
protected Result doInBackground(Params... params) {
// Kod działającym w tle
}
protected void onProgressUpdate(Progress... values) {
// Kod informujący o postępach prac
}
protected void onPostExecute(Result result) {
// Kod wykonany po zakończeniu zadania
}
}
Metoda onPreExecute jest wywoływana w głównym wątku. Ma dostęp do wszystkich widoków interfejsu użytkownika. Zwraca tylko wynik void.
przykład:
ContentValues kolorValues;
protected void onPreExecute() {
CheckBox czerwony = (CheckBox)findViewById(R.id.czerwony);
kolorValues= new ContentValues();
kolorValues.put("CZERWONY", czerwony.isChecked());
}
Metoda doInBackground() jest wywoływana po zakończeniu kodu w metodzie onPreExecute(). Możemy definiować jakiego typu będą parametry i jakiego typu dane zwróci wynik w metodzie onPostExecute(). Kod zostanie wykonany w tle.
przykład:
// Wykonujemy kod operujący na bazie danych w tle.
protected Boolean doInBackground(Integer... kolor) {
int kolorId = kolor[0];
SQLiteOpenHelper kolorDatabaseHelper = new KolorDatabaseHelper(KolorActivity.this);
try {
SQLiteDatabase db = kolorDatabaseHelper.getWritableDatabase();
db.update(
"KOLOR", kolorValues,
"_id = ?",
new String[] {Integer.toString(kolorId)}
);
db.close();
return true;
} catch(SQLiteException e) {
return false;
}
}
Metoda onProgressUpdate() ma dostęp do wszystkich widoków tworzących jej interfejs użytkownika. Dzięki tej metodzie mozna prezentować postęp wykonywanego kodu w tle, poprzez aktualizowanie stanu widoków. Możemy definiować typ parametru tej metody. Jeżeli w kodzie metody doInBackground() wywołamy metodę publishProgress(), wówczas zostanie wywołana metoda onProgressUpdate(). Nie musimy implementować tej metody.
przykład:
protected Boolean doInBackground(Integer... ile) {
for (int i = 0; i < ile; i++) {
publishProgress(i);
}
// wywołujemy metodę publishProgress() wartość zmiennej (i) przekazujemy do metody onProgressUpdate()
}
protected void onProgressUpdate(Integer... progress) {
setProgress(progress[0]);
}
Jeżeli nie będziemy korzystać z metody onProgressUpdate() parametr Progress określimy jako Void.
private class MojaKlasa extends AsyncTask<Integer, Progress, Boolean> {
...
}
// Progress na Void
private class MojaKlasa extends AsyncTask<Integer, Void, Boolean> {
...
}
Metoda onPostExecute() jest wywoływana po zakończeniu kodu w metodzie doInBackground(). Ma dostęp to widoków tworzących w interfejsie. Metoda doInBackground() przekazuje wynik do metody onPostExecute(), typ parametru musi odpowiadać typowi wyniku.
przykład:
protected void onPostExecute(Boolean koniec) {
if (!koniec) {
Toast toast = Toast.makeText(KolorActivity.this, "Baza danych jest niedostępna", Toast.LENGTH_SHORT);
toast.show();
}
}
Wywołując klasę AsyncTask przekazujemy do niej wszystkie parametry wymagane w metodzie doInBackground() poprzez metodę execute().
przykład:
new MojaAsyncTask().execute(kolorId);
Klasa AsyncTask wykonuje zadanie na SQLite.
przykład:
// Klasa wewnętrzna służąca do aktualizacji danych napoju
private class MojaAsyncTask extends AsyncTask<Integer, Void, Boolean> {
private ContentValues kolorValues;
protected void onPreExecute() {
// Przed wykonaniem kodu operującego na bazie
// danych zapisujemy wartość pola wyboru
// w obiekcie ContentValue przechowywanym
// w zmiennej kolorValues.
CheckBox kolorbox = (CheckBox) findViewById(R.id.kolorbox);
kolorValues = new ContentValues();
kolorValues.put("FAVORITE", kolorbox.isChecked());
}
// Wykonujemy kod operujący
// na bazie danych w tle.
protected Boolean doInBackground(Integer... kolory) {
int kolorId = kolory[0];
SQLiteOpenHelper kolorDatabaseHelper = new KolorDatabaseHelper(KolorActivity.this);
try {
SQLiteDatabase db = kolorDatabaseHelper.getWritableDatabase();
db.update(
"COLOR", kolorValues,
"_id = ?",
new String[] {Integer.toString(kolorId)}
);
db.close();
return true;
} catch(SQLiteException e) {
return false;
}
}
protected void onPostExecute(Boolean koniec) {
if (!koniec) {
Toast toast = Toast.makeText(KolorActivity.this, "Baza danych jest niedostępna", Toast.LENGTH_SHORT);
toast.show();
}
}
}
Klasa AsyncTask wykonuje zadanie na serwerze PHP - pobranie danych.
przykład:
public void onClickStartPHP(View view) {
new LoadDaneSerwerPHP().execute("https://www.ngnet.pl/");
}
private class LoadDaneSerwerPHP extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
NGtextView.setText("Czekaj!");
}
@Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
URLConnection connection = url.openConnection();
InputStream dane = new BufferedInputStream(connection.getInputStream());
return streamToString(dane);
} catch (Exception e) {
return null;
}
}
@Override
protected void onPostExecute(String result) {
try {
// JSON
JSONObject json = new JSONObject(result);
final TextView text_id = (TextView)findViewById(R.id.dane_serwera_id);
text_id.setText("identyfikator: " + json.optString("id"));
final TextView text_name = (TextView)findViewById(R.id.dane_serwera_name);
text_name.setText("nazwa: " + json.optString("name"));
NGtextView.setText("Gotowe!");
} catch (Exception e) {
Toast toast = Toast.makeText(MainActivity.this, "Serwer PHP niedostępny", Toast.LENGTH_SHORT);
toast.show();
}
}
}
protected String streamToString(InputStream dane) {
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(dane));
StringBuilder stringbuilder = new StringBuilder();
String line = null;
try {
while ((line = bufferedreader.readLine()) != null) {
stringbuilder.append(line + "\n");
}
bufferedreader.close();
} catch (IOException e) {
Toast toast = Toast.makeText(MainActivity.this, "error!1", Toast.LENGTH_SHORT);
toast.show();
}
return stringbuilder.toString();
}
Klasa AsyncTask wykonuje zadanie na serwerze PHP - wysłanie i pobranie danych.
przykład:
public void onClickStartPHP(View view) {
new LoadAndSendPHP().execute("https://www.ngnet.pl/");
}
private class LoadAndSendPHP extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
NGtextView.setText("Czekaj!");
}
@Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Ustawia limit czasu odczytu na określony limit czasu w milisekundach
connection.setReadTimeout(12000);
// Ustawia określoną wartość limitu czasu w milisekundach,
// która ma być używana podczas otwierania łącza komunikacyjnego do zasobu,
// do którego odwołuje się ten URLConnection
connection.setConnectTimeout(12000);
// Ustaw na true, jeśli zamierzasz używać połączenia URL do danych wyjściowych
connection.setDoOutput(true);
// Ustawia ogólną właściwość żądania
connection.setRequestProperty("Content-Type", "application/json");
// Ustaw metodę żądania adresu URL
connection.setRequestMethod("POST");
// Obiekt do wysłania
JSONObject data = new JSONObject();
data.put("name", ((EditText) findViewById(R.id.post_name)).getText().toString());
// Wysłaym obiekt
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
"UTF-8"));
writer.write(data.toString());
writer.close();
// sprawdzamy czy przyszła odpowiedź z serwera
// sprawdzenie czy strona istenieje kod 200 = OK, 400 = Bad Request
if (connection.getResponseCode() != 200) {
throw new BarException("Bad Request");
}
// odczytanie danych z serwera
InputStream dane = new BufferedInputStream(connection.getInputStream());
// konwersja na String
return streamToString(dane);
} catch (Exception e) {
// Log.d
Log.d(MainActivity.class.getSimpleName(), e.toString());
return null;
}
}
@Override
protected void onPostExecute(String result) {
try {
// JSON
JSONObject json = new JSONObject(result);
final TextView text_id = (TextView)findViewById(R.id.dane_serwera_id);
text_id.setText("identyfikator: " + json.optString("id"));
final TextView text_name = (TextView)findViewById(R.id.dane_serwera_name);
text_name.setText("nazwa: " + json.optString("name"));
NGtextView.setText("Gotowe!");
} catch (Exception e) {
Toast toast = Toast.makeText(MainActivity.this, "Serwer PHP niedostępny", Toast.LENGTH_SHORT);
toast.show();
}
}
}
protected String streamToString(InputStream dane) {
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(dane));
StringBuilder stringbuilder = new StringBuilder();
String line = null;
try {
while ((line = bufferedreader.readLine()) != null) {
stringbuilder.append(line + "\n");
}
bufferedreader.close();
} catch (IOException e) {
Toast toast = Toast.makeText(MainActivity.this, "error!1", Toast.LENGTH_SHORT);
toast.show();
}
return stringbuilder.toString();
}