0

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

我将讨论我所拥有的,如果有人能告诉我哪里出了问题/我应该做什么,我将不胜感激。

我有一个OnTaskCompleted在它自己的文件中调用的接口:

OnTask已完成:

package com.example;

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

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

连接工具:

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

我期望看到的是whileinisConnected()运行,而我们没有从 AsynTask 获得结果,并且一旦 Task 完成hasChecked设置为 true,然后停止 while 循环。

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

谁能解释我可能出错的地方和原因?

我可能应该注意,我对回调的一般工作方式而不是在这段代码中更感兴趣(尽管使用这段代码来解释)。这只是示例代码。

4

2 回答 2

1

使用AsyncTasks的目的是将 UI 线程释放给其他活动,同时在AsyncTask.

但是,在您的代码中,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);
    }
}

最后,我不确定你为什么需要一个Interfacehere:你可以完全取消它(就这个简单的示例代码而言)并直接在onPostExecute.

于 2013-08-26T00:20:47.110 回答
0

这就是 asynctask 回调的工作方式

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

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

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

  4. doInBackground() 的返回最终被 onPostExecute() 拿走。此回调再次有效地在 UI 线程上运行,并根据 asysntask 结果为 UI 线程做最后的工作。

有关详细信息,您可以查看以下链接:

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

希望这可以帮助你

于 2013-08-26T00:18:56.627 回答