Курс по Java/Android
Занятие 14
Александр Русин
e-mail: alexandr.rusin@gmail.com
Android Developer
Thread
●
наследовать Thread
●
реализовать Runnable(полное имя
java.lang.Runnable)
Пример способ 1
class DoSomethingThread extends Thread {
/**
* Здесь можно доопределить, конструктор, статические
поля и т.д.
*/
@Override
protected void run() {
super.run();
// здесь можно что-то делать
}
}
Пример способ 2
class DoSomething implements Runnable {
@Override
protected void run() {
// здесь можно что-то делать
// предка у этого класса нет
}
}
Запуск
DoSomethingThread thread = new DoSomethingThread();
th.start();
//Способ 2:
Thread thread = new Thread(new DoSomething());
thread.start();
Передача управления
другому потоку
class DoTask implements Runnable {
@Override
protected void run() {
while (true) {
/* рабочий код */
yield();
}
}
Sleep
class DoTask implements Runnable {
@Override
protected void run() {
while (true) {
/* рабочий код */
sleep(1000); // спим секунду
}
}
Остановка потока
class StopableTaskOne extends Thread {
private volatile boolean mIsStopped = false;
@Override
protected void run() {
super.run();
mIsStopped = false;
while (!mIsStopped) {
/*рабочий код */
}
}
public void stopThis() {
mIsStopped = true; // текущая итерация - последняя
}
}
Жизненный цикл потока
Жизненный цикл потока
●
Newly Create // между th =‘new Thread();’ и ‘th.start();’;
●
Started Thread (Runnable) // после ‘th.start();’, однако поток не обязан
выполняться в этот самый момент;
●
Started Thread (Running) // в этот самый момент выполняется код в
этом самом потоке;
●
Started Thread (Dead) // метода run исполнился до конца;
●
Blocked // выполняется другой поток, а наш yield(), sleep(), wait().
Cостояния runnable
Остановка потока
class StopableTaskTwo extends Thread {
private volatile boolean mIsStopped = false;
@Override
protected void run() {
super.run();
mIsStopped = false;
while (!mIsStopped) {
try {
/*рабочий код */
sleep(1000);
} catch (InterruptedException ex) {
/* вот теперь все, не смотря на процесс */
}
}
}
public void stopThis() {
mIsStopped = true; // текущая итерация - последняя
this.interrupt(); // и заканчивается она прямо сейчас
}
}
Остановка потока
class StopableTaskTwo extends Thread {
private volatile boolean mIsStopped = false;
@Override
protected void run() {
super.run();
mIsStopped = false;
while (!mIsStopped) {
/* собственно рабочий код */
yield();
if (isInterrupted() {
/* теперь все */
return ;
}
}
}
public void stopThis() {
mIsStopped = true; // текущая итерация - последняя
this.interrupt(); // и заканчивается она прямо сейчас
}
}
Класс Handler
●
dispatchMessage(Message msg) // обработчик системных сообщений
●
dump(Printer pw, String prefix) // дамп
●
handleMessage(Message msg) // обработчик входящих сообщений,
должен переопределятся потомками
●
hasMessages(int what, Object object) // проверяет есть ли не
обработанное сообщение с кодом 'what' и объектом сообщения 'object'
Класс Handler
●
hasMessages(int what) // проверяет есть ли не обработанное сообщение с кодом 'what'
●
Message obtainMessage() // новое сообщение из глобального пула сообщений, есть вариации
метода
●
boolean post(Runnable r) // послать r в очередь сообщений (т.е. выполнить код в потоке, в
котором объект Handle был создан)
●
void removeCallbacks(Runnable r) // удалить все посланные r из очереди сообщений
●
void removeMessages(int what) // удалить сообщение с кодом 'what' из очереди
●
boolean sendMessage(Message msg) // поместить сообщение в конец очереди сообщений
метод runOnUiThread
// снипет подгрузки изображения из интернета и установки его в виджет ImageView
(new Thread(new Runnable() {
@Override
public void run() {
try {
final Bitmap bm = ImageTool.loadBitmap(urlImg);
CompanyView.this.runOnUiThread(new Runnable() {
@Override
public void run() {
ico.setImageBitmap(bm);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
})).start();
Класс AsyncTask
// Шаблон класса использует три типа
●
Params // тип параметров посылаемых
перед запуском задачи;
●
Progress // тип, используемый для
отображения прогресса операции;
●
Result // тип результата задачи;
Класс AsyncTask
●
OnPreExecute() // вызывается в потоке UI
сразу после запуска задачи, на данном этапе
обычно настраивают задачу, например,
показывая индикатор прогресса в UI;
●
doInBackground(Params...) // запускается в
отдельном потоке после завершения
onPreExecute(). На этом этапе вычисляется
результат, который передается методу
onPostExecute;
Класс AsyncTask
●
onProgressUpdate(Progress...) // вызывается в
потоке UI сразу после вызова publishProgress().
Метод используется для отображения прогресса в
пользовательском интерфейсе;
●
onPostExecute(Result) // вызывается в потоке UI
после завершения задачи;
●
execute(Params... params) // выполняет задачу с
указанными параметрами;
●
IsCancelled() // true, если задача была прервана;
●
cancel(boolean mayInterruptIfRunning) // попытка
прервать задачу;
Пример
// пример из документации - загрузка файлов
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
new DownloadFilesTask().execute(url1, url2, url3); // исполнетние task
Повторный запуск
// При повторном запуске задачи система выдаст ошибку
// Cannot execute task: the task has already been executed
// (a task can be executed only once)
at = new DownloadFilesTask();
at.execute(url1, url2, url3);
...
at.execute(url1, url2, url3);
// правильно
at = new DownloadFilesTask();
at.execute(url1, url2, url3);
...
at = new DownloadFilesTask();
at.execute(url1, url2, url3);
метод View.post
TextView tvDescription;
...
tvDescription.setText("example for darkraha.com"));
tvDescription.post(new Runnable() {
@Override
public void run() {
if(tvDescription.getMeasuredHeight() > getCollapsedHeight()){
evDescription.setCollapse();
}
}
});
Домашнее задание
1. Сделать в потоке чтение файла (.txt). Мин
размер файла 1 Мб с progressBar.
2. Загрузка из сети нескольких картинок в
ListView c progressBar.
Литература
1. http://idev.by/android/8729/
2. http://idev.by/android/11239/
3. http://developer.alexanderklimov.ru/android/thread.php
5. http://darkraha.com/rus/mobile/android/api/threads.php
6. http://habrahabr.ru/post/124484/
7. http://www.4stud.info/rtos/lecture2.html
Спасибо за внимание!

Lec 14

  • 1.
    Курс по Java/Android Занятие14 Александр Русин e-mail: alexandr.rusin@gmail.com Android Developer
  • 2.
  • 3.
    Пример способ 1 classDoSomethingThread extends Thread { /** * Здесь можно доопределить, конструктор, статические поля и т.д. */ @Override protected void run() { super.run(); // здесь можно что-то делать } }
  • 4.
    Пример способ 2 classDoSomething implements Runnable { @Override protected void run() { // здесь можно что-то делать // предка у этого класса нет } }
  • 5.
    Запуск DoSomethingThread thread =new DoSomethingThread(); th.start(); //Способ 2: Thread thread = new Thread(new DoSomething()); thread.start();
  • 6.
    Передача управления другому потоку classDoTask implements Runnable { @Override protected void run() { while (true) { /* рабочий код */ yield(); } }
  • 7.
    Sleep class DoTask implementsRunnable { @Override protected void run() { while (true) { /* рабочий код */ sleep(1000); // спим секунду } }
  • 8.
    Остановка потока class StopableTaskOneextends Thread { private volatile boolean mIsStopped = false; @Override protected void run() { super.run(); mIsStopped = false; while (!mIsStopped) { /*рабочий код */ } } public void stopThis() { mIsStopped = true; // текущая итерация - последняя } }
  • 9.
  • 10.
    Жизненный цикл потока ● NewlyCreate // между th =‘new Thread();’ и ‘th.start();’; ● Started Thread (Runnable) // после ‘th.start();’, однако поток не обязан выполняться в этот самый момент; ● Started Thread (Running) // в этот самый момент выполняется код в этом самом потоке; ● Started Thread (Dead) // метода run исполнился до конца; ● Blocked // выполняется другой поток, а наш yield(), sleep(), wait().
  • 11.
  • 12.
    Остановка потока class StopableTaskTwoextends Thread { private volatile boolean mIsStopped = false; @Override protected void run() { super.run(); mIsStopped = false; while (!mIsStopped) { try { /*рабочий код */ sleep(1000); } catch (InterruptedException ex) { /* вот теперь все, не смотря на процесс */ } } } public void stopThis() { mIsStopped = true; // текущая итерация - последняя this.interrupt(); // и заканчивается она прямо сейчас } }
  • 13.
    Остановка потока class StopableTaskTwoextends Thread { private volatile boolean mIsStopped = false; @Override protected void run() { super.run(); mIsStopped = false; while (!mIsStopped) { /* собственно рабочий код */ yield(); if (isInterrupted() { /* теперь все */ return ; } } } public void stopThis() { mIsStopped = true; // текущая итерация - последняя this.interrupt(); // и заканчивается она прямо сейчас } }
  • 14.
    Класс Handler ● dispatchMessage(Message msg)// обработчик системных сообщений ● dump(Printer pw, String prefix) // дамп ● handleMessage(Message msg) // обработчик входящих сообщений, должен переопределятся потомками ● hasMessages(int what, Object object) // проверяет есть ли не обработанное сообщение с кодом 'what' и объектом сообщения 'object'
  • 15.
    Класс Handler ● hasMessages(int what)// проверяет есть ли не обработанное сообщение с кодом 'what' ● Message obtainMessage() // новое сообщение из глобального пула сообщений, есть вариации метода ● boolean post(Runnable r) // послать r в очередь сообщений (т.е. выполнить код в потоке, в котором объект Handle был создан) ● void removeCallbacks(Runnable r) // удалить все посланные r из очереди сообщений ● void removeMessages(int what) // удалить сообщение с кодом 'what' из очереди ● boolean sendMessage(Message msg) // поместить сообщение в конец очереди сообщений
  • 16.
    метод runOnUiThread // снипетподгрузки изображения из интернета и установки его в виджет ImageView (new Thread(new Runnable() { @Override public void run() { try { final Bitmap bm = ImageTool.loadBitmap(urlImg); CompanyView.this.runOnUiThread(new Runnable() { @Override public void run() { ico.setImageBitmap(bm); } }); } catch (Exception e) { e.printStackTrace(); } } })).start();
  • 17.
    Класс AsyncTask // Шаблонкласса использует три типа ● Params // тип параметров посылаемых перед запуском задачи; ● Progress // тип, используемый для отображения прогресса операции; ● Result // тип результата задачи;
  • 18.
    Класс AsyncTask ● OnPreExecute() //вызывается в потоке UI сразу после запуска задачи, на данном этапе обычно настраивают задачу, например, показывая индикатор прогресса в UI; ● doInBackground(Params...) // запускается в отдельном потоке после завершения onPreExecute(). На этом этапе вычисляется результат, который передается методу onPostExecute;
  • 19.
    Класс AsyncTask ● onProgressUpdate(Progress...) //вызывается в потоке UI сразу после вызова publishProgress(). Метод используется для отображения прогресса в пользовательском интерфейсе; ● onPostExecute(Result) // вызывается в потоке UI после завершения задачи; ● execute(Params... params) // выполняет задачу с указанными параметрами; ● IsCancelled() // true, если задача была прервана; ● cancel(boolean mayInterruptIfRunning) // попытка прервать задачу;
  • 20.
    Пример // пример издокументации - загрузка файлов private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); } return totalSize; } protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } } new DownloadFilesTask().execute(url1, url2, url3); // исполнетние task
  • 21.
    Повторный запуск // Приповторном запуске задачи система выдаст ошибку // Cannot execute task: the task has already been executed // (a task can be executed only once) at = new DownloadFilesTask(); at.execute(url1, url2, url3); ... at.execute(url1, url2, url3); // правильно at = new DownloadFilesTask(); at.execute(url1, url2, url3); ... at = new DownloadFilesTask(); at.execute(url1, url2, url3);
  • 22.
    метод View.post TextView tvDescription; ... tvDescription.setText("examplefor darkraha.com")); tvDescription.post(new Runnable() { @Override public void run() { if(tvDescription.getMeasuredHeight() > getCollapsedHeight()){ evDescription.setCollapse(); } } });
  • 23.
    Домашнее задание 1. Сделатьв потоке чтение файла (.txt). Мин размер файла 1 Мб с progressBar. 2. Загрузка из сети нескольких картинок в ListView c progressBar.
  • 24.
    Литература 1. http://idev.by/android/8729/ 2. http://idev.by/android/11239/ 3.http://developer.alexanderklimov.ru/android/thread.php 5. http://darkraha.com/rus/mobile/android/api/threads.php 6. http://habrahabr.ru/post/124484/ 7. http://www.4stud.info/rtos/lecture2.html
  • 25.