AsyncTask回调停止while循环,澄清它是如何工作的?

时间:2013-08-25 23:56:01

标签: android android-asynctask asynccallback

我正试图在AsyncTasks中使用回调,因为它似乎是如何从任务更新的标准...问题是我似乎无法让它工作,因为在线资源似乎在说“做这个,它会起作用”而不是通过它来讨论。

我要谈谈我所拥有的,如果有人能告诉我哪里出错了/我应该做什么,我会很感激。

我在其自己的文件中有一个名为OnTaskCompleted的界面:

OnTaskCompleted:

package com.example;

public interface OnTaskCompleted{
    void onTaskCompleted(boolean result);
}

然后我有另一个包含一些方法的任务,以及我的AsyncTask

ConnectUtils:

public class ConnectUtils implements OnTaskCompleted {

    private boolean hasConnected, hasChecked;

    public boolean isConnected(Context parent, String url){ 
        hasChecked = false;
        new CheckURL(parent, new OnTaskCompleted(){
            @Override
            public void onTaskCompleted(boolean result) {
                // TODO Auto-generated method stub

            }}, url).execute();
        while(!hasChecked){ Log.i("Checked?", hasChecked + ""); }
        return hasConnected;
    }

    private class CheckURL extends AsyncTask<Void, Void, Boolean>{

        private Context parent;
        private OnTaskCompleted listener;
        private String url;

        public CheckURL(Context parent, OnTaskCompleted listener, String url){
            this.parent = parent;
            this.listener = listener;
            this.url = url;
        }

        @Override
        protected Boolean doInBackground(Void... params){
            // Do some stuff and return a boolean
        }

        @Override
        protected void onPostExecute(Boolean result){
            super.onPostExecute(result);
            listener.onTaskCompleted(result);
        }
    }


    @Override
    public void onTaskCompleted(boolean result) {
        Log.i("Completed", result + "");
        hasConnected = result;
        hasChecked = true;
    }
}

我期待看到的是while中的isConnected()在我们没有来自AsynTask的结果时运行,并且一旦任务完成hasChecked设置为真,然后停止while循环。

我所看到的是,循环是无限延续的,只是不断地记录错误,因此hasChecked没有被更新。

任何人都可以解释我可能出错的地点和原因吗?

我应该注意到我对回调如何工作而不是在这段代码中更感兴趣(尽管使用这段代码来解释)。这只是示例代码。

2 个答案:

答案 0 :(得分:1)

使用AsyncTasks的目的是将UI线程释放到其他活动,而某些处理在AsyncTask的非UI线程上完成。

但是,在您的代码中,UI线程(获取优先级)被锁定到while()循环中,等待非UI线程(不会获得优先级)来完成AsyncTask

更好的方法是不同的流程。首先,启动连接:

public void ensureConnected(Context parent, String url){ 
    new CheckURL(parent, new OnTaskCompleted(){
        @Override
        public void onTaskCompleted(boolean result) {
            isChecked   = true;
            isConnected = result;

            // Change of state actions called from here
        }}, url).execute();
}

AsyncTask

private class CheckURL extends AsyncTask<Void, Void, Boolean>{
    private Context parent;
    private OnTaskCompleted listener;
    private String url;

    public CheckURL(Context parent, OnTaskCompleted listener, String url){
        this.parent = parent;
        this.listener = listener;
        this.url = url;
    }

    @Override
    protected Boolean doInBackground(Void... params){
        // Do some stuff and return a boolean
    }

    @Override
    protected void onPostExecute(Boolean result){
        super.onPostExecute(result);
        listener.onTaskCompleted(result);
    }
}

最后,我不确定你为什么需要一个Interface:你可以完全取消它(就这个简单的示例代码而言)并设置状态变量并触发状态改变动作直接在onPostExecute

答案 1 :(得分:0)

这是asynctask回调的工作方式

  1. 首先调用onPreExecute(),它有效地在UI线程上运行,因此您可以在线程启动之前在此处执行一些UI活动。例如,您可以在此处启动进度对话框。

  2. 然后调用doInBackgound(),其中线程工作在后台完成。您可以通过使用中间值调用函数publishProgress(int)将中间结果发布到UI线程。

  3. 中间值从onPublishProgress()发布到UI线程。

  4. doInBackground()的返回最终由onPostExecute()获取。这个回调再次有效地在UI线程上运行,并根据asysntask结果完成UI线程的最终工作。

  5. 有关详细信息,请查看以下链接:

    http://developer.android.com/reference/android/os/AsyncTask.html

    希望这有助于你