AsyncTask的从处理程序称为将不会执行doInBackground [英] AsyncTask called from Handler will not execute doInBackground

查看:160
本文介绍了AsyncTask的从处理程序称为将不会执行doInBackground的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个后台线程通过API来下载图像列表的应用程序,然后在幻灯片显示图像。

有一个后台任务(目前的AsyncTask)定期获取新的图像。

我没有收到关于错误的线程等任何错误信息,它只是在AsyncTasks的第二个实例将不会运行doInBackground方法。

下面是从活动的一些code:

 私人DownloadTask mDownloadTask = NULL;
私人处理器mHandler;

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);

    mHandler =新的处理程序(){
        @覆盖
        公共无效的handleMessage(信息MSG){
            如果(mDownloadTask!= NULL){
                mDownloadTask.cancel(真正的);
            }
            mDownloadTask =新DownloadTask();
            mDownloadTask.execute((无效[])NULL);
        }
    };

    mDownloadTask =新DownloadTask();
    mDownloadTask.execute((无效[])NULL);
}
 

DownloadTask 是这样的:

  @覆盖
受保护的名单,其中,字符串> doInBackground(虚空......空隙){
     //下载从服务器等的URL列表
}

@覆盖
保护无效onPostExecute(名单<字符串>网址){
    mHandler.sendEmptyMessageDelayed(111,5000);
}
 

该处理器将被调用,在preExecute(在AsyncTask的)将被调用,DownloadTask的初始运行(右的onCreate )也适用。

根据这个问题:<一href="http://stackoverflow.com/questions/9119627/android-sdk-asynctask-doinbackground-not-running-subclass">Android SDK的AsyncTask doInBackground没有运行(子类),它可能是SDK15相关。

感谢您的任何提示。


更新作为我收到的意见,该处理器可能不会在UI线程(这是奇怪的,因为 Thread.currentThread 是一样的无论是在的onCreate和处理程序的handleMessage 的方法,我修改了的handleMessage 方法:

  mHandler =新的处理程序(){
    @覆盖
    公共无效的handleMessage(信息MSG){
        runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                如果(mDownloadTask!= NULL){
                    mDownloadTask.cancel(真正的);
                }
                mDownloadTask =新DownloadTask();
                mDownloadTask.execute((无效[])NULL);
            }
        });
    }
};
 

不过没有成功。


更新全面DownloadTask类

 类DownloadTask扩展的AsyncTask&LT;虚空,虚空,列表和LT;字符串&GT;&GT; {

    @覆盖
    在preExecute保护无效(){
        //取消动画。
        如果(mSlideshowAnimation!= NULL){
            mSlideshowAnimation.cancel(真正的);
        }

        mImageView1.setVisibility(View.GONE);
        mImageView2.setVisibility(View.GONE);
        动画(mProgressBar)阿尔法(1.0F).setDuration(500)。开始();

        Log.d(TAG,下载preparation完成。);
    }

    @覆盖
    受保护的名单,其中,字符串&GT; doInBackground(虚空......空隙){
        Log.d(TAG,下载);
        共享preferences S = getShared preferences(访问,Context.MODE_PRIVATE);
        字符串标记= s.getString(令牌,NULL);

        Log.d(TAG,下载幻灯片。);

        名单&LT;字符串&GT;网址=新的ArrayList&LT;字符串&GT;();
        幻灯片[]幻灯片=新的API(SlideshowActivity.this).getSlideshows(标记);
        对于(幻灯片播放幻灯片:幻灯片){
            urls.addAll(slideshow.getAllPhotoUrls());
        }

        Log.d(TAG,下载幻灯片:+ slideshows.length);

        对于(字符串网址:网址){
            尝试 {
                URL = Api.HOST +网址;

                如果(!Cache.fileExists(Cache.getCacheFilenameForUrl(SlideshowActivity.this,URL))){
                    Cache.cacheStream(SlideshowActivity.this,HttpHelper.download(SlideshowActivity.this,URL),URL);
                } 其他 {
                    Log.d(TAG,缓存:+网址);
                }
            }赶上(IOException异常E){
                Log.e(TAG,错误边下载,E);
            }
        }

        Log.d(TAG,下载幻灯片结束了。);

        返回的网址;
    }

    @覆盖
    保护无效onPostExecute(名单&LT;字符串&GT;网址){
        Log.d(TAG,下载成功);
        动画(mProgressBar)阿尔法(0.0).setDuration(500)。开始();

        mCurrentImageIndex = -1;
        mImageUrls =网址;

        mSlideshowAnimation =新SlideshowAnimation();
        mSlideshowAnimation.execute((无效[])NULL);

        mHandler.sendEmptyMessageDelayed(111,5000);
    }
}
 

解决方案

由于与Waqas一个有益的讨论(谢谢!)我终于在我的code发现的错误。事实上,所有上面写的是正确的,工作原理是。问题与我的情况是,第二个任务挡住了第一个,反之亦然。

这也许是一个巧合找到这个职位上谷歌群组:<一href="http://groups.google.com/group/android-developers/browse_thread/thread/f0cd114c57ceefe3?tvc=2&q=AsyncTask+in+Android+4.0">http://groups.google.com/group/android-developers/browse_thread/thread/f0cd114c57ceefe3?tvc=2&q=AsyncTask+in+Android+4.0 。建议每个人都参与线程仔细阅读本次讨论。

AsyncTask的切换线程模型到串行执行人(再次),这是不符合我的具有2 AsyncTasks似乎的方法兼容。

最后,我切换的下载的处理,以经典的和使用处理程序发布的消息如果neccessary取消幻灯片。使用处理程序 sendEmptyMessageDelayed 我会简单的重新建立一段时间后,下载线程刷新数据。

感谢所有的意见和放大器;的回答。

The application I'm working on is using a background thread to download a list of images through a API, then display the images in a slideshow.

There is a background task (currently AsyncTask) to periodically fetch the new images.

I'm not getting any error messages about the wrong Thread etc, it's just that the AsyncTasks's second instance will not run the doInBackground method.

Here is some code from the Activity:

private DownloadTask mDownloadTask = null;
private Handler mHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(mDownloadTask != null) {
                mDownloadTask.cancel(true);
            }
            mDownloadTask = new DownloadTask();
            mDownloadTask.execute((Void[]) null);
        }
    };

    mDownloadTask = new DownloadTask();
    mDownloadTask.execute((Void[]) null);
}

The DownloadTask looks like this:

@Override
protected List<String> doInBackground(Void... voids) {
     // Download list of URLs from server, etc.
}

@Override
protected void onPostExecute(List<String> urls) {
    mHandler.sendEmptyMessageDelayed(111, 5000);
}

The handler will be called, the onPreExecute (in the AsyncTask) will be called and the initial run of DownloadTask (right in onCreate) also works.

According to this question: Android SDK AsyncTask doInBackground not running (subclass) , it might be SDK15 related.

Thanks for any hints.


Update As I received comments that the Handler might not be in the UI thread (which is weird, as Thread.currentThread is the same both in onCreate and the Handlers handleMessage method, I revised the handleMessage method to:

mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(mDownloadTask != null) {
                    mDownloadTask.cancel(true);
                }
                mDownloadTask = new DownloadTask();
                mDownloadTask.execute((Void[]) null);
            }
        });
    }
};

Still without success.


Update the full DownloadTask class

class DownloadTask extends AsyncTask<Void, Void, List<String>> {

    @Override
    protected void onPreExecute() {
        // Cancel the animation.
        if (mSlideshowAnimation != null) {
            mSlideshowAnimation.cancel(true);
        }

        mImageView1.setVisibility(View.GONE);
        mImageView2.setVisibility(View.GONE);
        animate(mProgressBar).alpha(1.0f).setDuration(500).start();

        Log.d(TAG, "Download preparation done.");
    }

    @Override
    protected List<String> doInBackground(Void... voids) {
        Log.d(TAG, "Download");
        SharedPreferences s = getSharedPreferences("access", Context.MODE_PRIVATE);
        String token = s.getString("token", null);

        Log.d(TAG, "Downloading slideshows.");

        List<String> urls = new ArrayList<String>();
        Slideshow[] slideshows = new Api(SlideshowActivity.this).getSlideshows(token);
        for (Slideshow slideshow : slideshows) {
            urls.addAll(slideshow.getAllPhotoUrls());
        }

        Log.d(TAG, "Downloading slideshows: " + slideshows.length);

        for (String url : urls) {
            try {
                url = Api.HOST + url;

                if (!Cache.fileExists(Cache.getCacheFilenameForUrl(SlideshowActivity.this, url))) {
                    Cache.cacheStream(SlideshowActivity.this, HttpHelper.download(SlideshowActivity.this, url), url);
                } else {
                    Log.d(TAG, "Cached: " + url);
                }
            } catch (IOException e) {
                Log.e(TAG, "Error while downloading.", e);
            }
        }

        Log.d(TAG, "Downloading slideshows finished.");

        return urls;
    }

    @Override
    protected void onPostExecute(List<String> urls) {
        Log.d(TAG, "download successful");
        animate(mProgressBar).alpha(0.0f).setDuration(500).start();

        mCurrentImageIndex = -1;
        mImageUrls = urls;

        mSlideshowAnimation = new SlideshowAnimation();
        mSlideshowAnimation.execute((Void[]) null);

        mHandler.sendEmptyMessageDelayed(111, 5000);
    }
}

解决方案

Thanks to a helpful discussion with Waqas (thank you!) I finally uncovered the error in my code. In fact all above written is correct and works as is. Issue with my case was that the second task blocked the first one and vice versa.

It was perhaps a coincidence to find this post on Google Groups: http://groups.google.com/group/android-developers/browse_thread/thread/f0cd114c57ceefe3?tvc=2&q=AsyncTask+in+Android+4.0 . Recommend that everyone involved in threading reads this discussion carefully.

AsyncTask switched the Threading model to a serial executor (again), which is not compatible with my approach of having 2 AsyncTasks it seems.

Finally I switched the handling of the "Download" to a classic Thread and used the Handler to post messages to cancel the Slideshow if neccessary. Using the Handlers sendEmptyMessageDelayed I will simple recreate the Download Thread after a while to refresh the data.

Thanks to all comments & answers.

这篇关于AsyncTask的从处理程序称为将不会执行doInBackground的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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