Темы Android: остановка потока с тяжелыми вычислениями
Я делаю некоторые тяжелые вычисления в моем приложении для Android. Так как я не хочу блокировать UI-поток, я делаю вычисления в отдельном WorkerThread, который расширяет Thread. Это отлично работает. Но у меня проблемы с остановкой потока. Обычный способ остановить поток - использовать interrupt() или переменную volatile, чтобы сообщить потоку, что он должен завершиться. Но это работает только в потоках с какой-то петлей. Я делаю вычисления в потоке с использованием внешних библиотек, и я не могу поставить isInterrupted()- проверить в этой библиотеке. Плохой способ остановить поток - использовать метод stop()- метод, который устарел, но в моем случае это правильный путь, поскольку поток манипулирует только внутренними значениями. К сожалению, Android не поддерживает stop(), поскольку не поддерживает устаревшие методы потоков.
10-18 10:26:39.382: ERROR/global(13919): Deprecated Thread methods are not supported.
10-18 10:26:39.382: ERROR/global(13919): java.lang.UnsupportedOperationException
Есть ли у вас какой-либо другой способ остановить поток в Android? Заранее спасибо! Тобиас
PS: некоторый код, чтобы показать проблему:
public void method()
{
WorkerThread t = new WorkerThread();
t.start();
synchronized (this)
{
try
{
wait(1000);
} catch (InterruptedException e)
{
Log.e("",e.toString(),e);
}
}
//t.stop(); //not supported in android
//t.interrupt(); //can not be checked by the thread
}
class WorkerThread extends Thread
{
public void run()
{
externalLibrary.heavyComputation();
}
}
2 ответа
Обычно, если ваша внешняя библиотека не предоставляет какой-либо протокол для остановки вычислений, нет способа остановить это изящно. Многие хорошо написанные библиотеки предоставляют такой протокол, поэтому посмотрите его API. Также это может уважать interrupt()
вызов. Может быть, вы уже проверили его, но может пройти некоторое время, прежде чем он выйдет.
Смотреть на AsyncTask
, Это более правильный и гораздо более удобный способ реализации фоновых задач. Как вы можете прочитать в документации:
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");
}
}