AsyncTask的和线程不会在Java / Android应用程序运行两次 [英] AsyncTask and Thread won't run twice in java / android application

查看:104
本文介绍了AsyncTask的和线程不会在Java / Android应用程序运行两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android应用程序,用Java编写的,它使用的的AsyncTask 以下载数据。在的AsyncTask 是需要处理的进度对话框这是整个下载中。

实际下载是通过一个单独的线程开始, downloadAllUpdater 。虽然我知道这是不是习惯,需要一个线程作为下载的过程是S $ P $垫在7个班,没有其他的方式来更新进度条,同时下载正在发生,因为我无法运行 publishProgress 从其它类调用。

我的主要活动如下所示:

 私人下载downloadAll;私人诠释totalBlocksLeft;私人布尔DownloadComplete等;
私人布尔downloadFailed;私人PerformTask currentPerformTask;公共无效downloadAllClick(查看视图)//当下载所有按钮被点击
{
    currentPerformTask =新PerformTask();    currentPerformTask.execute();
}私有类PerformTask扩展的AsyncTask<无效,整型,整数GT;
{
    在preExecute保护无效()
    {
        usingDialog =新ProgressDialog(WifiAudioActivity.this);        usingDialog.show();
    }    保护整数doInBackground(无效... VOI)
    {
        downloadAll =新下载();        DownloadComplete等= FALSE; //假设下载不完整        downloadAllUpdater.start();        downloadFailed = FALSE;        而((DownloadComplete等==假)及及(downloadFailed == FALSE))
        {
            blocksDownloaded = downloadAll.getTotalBlocksLeft();            publishProgress(blocksDownloaded);
        }        返回0;
    }    保护无效onProgressUpdate(整数...进度)
    {
        usingDialog.setProgress(进展[0]);
    }    保护无效onPostExecute(整数结果)
    {
        usingDialog.dismiss();
    }
}螺纹downloadAllUpdater =新主题()
{
    公共无效的run()
    {
        INT runRetryCount = 0;        而(((DownloadComplete等))及!&安培;!((downloadFailed)))
        {
            DownloadComplete等= download.downloadAudio(totalBlocksLeft); //下载音频            如果(!(DownloadComplete等))
            {
                runRetryCount ++;
            }            如果(runRetryCount> Consts.RETRY_TOTAL)
            {
                downloadFailed = TRUE;
            }
        }
    }
};

下载与按钮的点击,从而启动在 downloadAllClick()方式启动。

这一切工作正常第一次按钮pressed。

然而,当按钮是pressed第二次(第一次completition)后,我收到一个错误,程序强制关闭。

我是pretty肯定错误是因为我运行的线程, downloadAllUpdater 第二次,因为如果我只用 downloadAllUpdater.start一个单独的方法(),它也崩溃,并显示同样的错误。

谁能帮助?下面是错误日志:

  11月8日至23日:22:34.954:W / dalvikvm(1485):主题ID = 14:螺纹未捕获的异常(组= 0x400259f8)退出11月8日至23日:22:35.014:E / AndroidRuntime(1485):致命异常:AsyncTask的#511月8日至23日:22:35.014:E / AndroidRuntime(1485):了java.lang.RuntimeException:执行doInBackground发生错误()11月8日至23日:22:35.014:E / AndroidRuntime(1485):在android.os.AsyncTask $ 3.done(AsyncTask.java:200)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:273)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.FutureTask.setException(FutureTask.java:124)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:307)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.FutureTask.run(FutureTask.java:137)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:561)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.lang.Thread.run(Thread.java:1102)11月8日至23日:22:35.014:E / AndroidRuntime(1485):java.lang.IllegalThreadStateException:由造成螺纹已经开始。11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.lang.Thread.start(Thread.java:1331)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在com.que.wifiaudio.WifiAudioActivity $ PerformTask.doInBackground(WifiAudioActivity.java:518)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在com.que.wifiaudio.WifiAudioActivity $ PerformTask.doInBackground(WifiAudioActivity.java:1)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在android.os.AsyncTask $ 2.call(AsyncTask.java:185)11月8日至23日:22:35.014:E / AndroidRuntime(1485):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)11月8日至23日:22:35.014:E / AndroidRuntime(1485):... 4个


解决方案

您不能启动线程的两倍。你可以让 downloadAllUpdater 一个Runnable来代替:

 的Runnable downloadAllUpdater =新的Runnable(){//其余部分不变

和与替换code在 doInBackground

 新的Thread(downloadAllUpdater)。开始();

这样,一个新的线程创建的每个时间,运行相同的任务。

doInBackground 已经在后台线程运行的,你确定你需要创建一个新的线程?如果没有,只是运行可运行: downloadAllUpdater.run(); 而无需创建一个新的线程

I have an android app, written in java which uses AsyncTask to download data. The AsyncTask is needed to handle the progress dialog box which is shown throughout the download.

The actual download is initiated through a separate thread, downloadAllUpdater. Whilst I am aware this is not convention, a thread is required as the process of downloading is spread across 7 classes and there was no other way to update the progress bar whilst the download was occurring as I couldn't run the publishProgress call from any other class.

My main activity is shown below:

private Download downloadAll;

private int totalBlocksLeft;

private boolean downloadComplete;
private boolean downloadFailed;

private PerformTask currentPerformTask;

public void downloadAllClick(View view) //When the download all button is clicked
{
    currentPerformTask = new PerformTask();

    currentPerformTask.execute();
}

private class PerformTask extends AsyncTask<Void, Integer, Integer>
{
    protected void onPreExecute()
    {
        usingDialog = new ProgressDialog(WifiAudioActivity.this);

        usingDialog.show();
    }

    protected Integer doInBackground(Void... voi) 
    {
        downloadAll = new Download();

        downloadComplete = false;   //Assume the download is not complete

        downloadAllUpdater.start(); 

        downloadFailed = false;

        while ((downloadComplete == false) && (downloadFailed == false))   
        {
            blocksDownloaded = downloadAll.getTotalBlocksLeft();

            publishProgress(blocksDownloaded);
        }

        return 0;
    }

    protected void onProgressUpdate(Integer... progress) 
    {
        usingDialog.setProgress(progress[0]);
    }

    protected void onPostExecute(Integer result) 
    {
        usingDialog.dismiss();
    }
}

Thread downloadAllUpdater = new Thread()
{
    public void run() 
    {
        int runRetryCount = 0;

        while ((!(downloadComplete)) && (!(downloadFailed)))
        {
            downloadComplete = download.downloadAudio(totalBlocksLeft);  //Download the audio

            if (!(downloadComplete))
            {
                runRetryCount++;
            }

            if (runRetryCount > Consts.RETRY_TOTAL)
            {
                downloadFailed = true;
            }
        }
    }
};

The download is initiated with the click of the button, which initiates the downloadAllClick() method.

This all works fine the first time the button is pressed.

However, when the button is pressed a second time (after the first time completition), I receive an error and the program force closes.

I am pretty sure the error is because I am running the Thread, downloadAllUpdater a second time, because if I have a separate method with just downloadAllUpdater.start(), it also crashes with the same error.

Can anyone help? Below is the error log:

08-23 11:22:34.954: W/dalvikvm(1485): threadid=14: thread exiting with uncaught exception (group=0x400259f8)

08-23 11:22:35.014: E/AndroidRuntime(1485): FATAL EXCEPTION: AsyncTask #5

08-23 11:22:35.014: E/AndroidRuntime(1485): java.lang.RuntimeException: An error occured while executing doInBackground()

08-23 11:22:35.014: E/AndroidRuntime(1485):     at android.os.AsyncTask$3.done(AsyncTask.java:200)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.lang.Thread.run(Thread.java:1102)

08-23 11:22:35.014: E/AndroidRuntime(1485): Caused by: java.lang.IllegalThreadStateException: Thread already started.

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.lang.Thread.start(Thread.java:1331)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at com.que.wifiaudio.WifiAudioActivity$PerformTask.doInBackground(WifiAudioActivity.java:518)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at com.que.wifiaudio.WifiAudioActivity$PerformTask.doInBackground(WifiAudioActivity.java:1)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at android.os.AsyncTask$2.call(AsyncTask.java:185)

08-23 11:22:35.014: E/AndroidRuntime(1485):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

08-23 11:22:35.014: E/AndroidRuntime(1485):     ... 4 more

解决方案

You can't start a Thread twice. You could make downloadAllUpdater a Runnable instead:

Runnable downloadAllUpdater = new Runnable() { //rest unchanged

And replace the code in doInBackground with:

new Thread(downloadAllUpdater).start();

That way, a new thread is created every time, running the same task.

However doInBackground is already running on a background thread, are you sure you need to create a new thread? If not, just run the runnable: downloadAllUpdater.run(); without creating a new thread.

这篇关于AsyncTask的和线程不会在Java / Android应用程序运行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆