android threads: stopping a thread with heavy computation

522 Views Asked by At

I am doing some heavy computation in my android application. Since i dont want to block the UI-thread, I do the computation in a seperate WorkerThread, which extends Thread. This works fine. But i have trouble stopping the thread. The normal way to stop a thread is either using interrupt() oder a volatile variable to tell the thread, that it should end. But this works only in Threads with some kind of loop. I am doing computation in the thread by using external libraries and I cannot put the isInterrupted()-check into this library. The bad way to stop a thread is using the stop()-Methode, which is deprecated, but in my case the right way, since the thread manipulates only internal values. Unfortunatly Android doesnt support stop(), since it doesn't support deprecated thread methods.

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

Do you now any other method to stop a thread in android? Thanks in advance! Tobias

PS: some code to show the problem:

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

There are 2 best solutions below

1
On BEST ANSWER

Generally, unless your external library provides some protocol to stop computation there is no way to stop it gracefully. Many well written libraries will do provide such protocol, so look at its api. Also it may respect interrupt() call. May be you already checked it but it may also take some time before it exits.

5
On

Look at AsyncTask. It is more proper and far more comfortable way to implement background tasks. As you can read in documentation:

 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");
     }
 }