3

我正在尝试从 DoInBackground 中的异步任务返回值,但调用 get() 方法会冻结我的 UI。如何将我的代码重写为回调方法?:

public class GetUrlDataTask extends AsyncTask<String, Integer, String> {
String response;
HttpUtils util;
@Override
protected String doInBackground(String... params) {
    try {
        util = new HttpUtils(params[0]);
        response = util.getContent();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return response;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
}

在我的活动中,我得到的结果为response = new GetUrlDataTask().execute("site").get;

4

4 回答 4

10

[更新] 现在我建议使用注释。使用注释,您可以注入视图,只需几个字母即可在编译步骤中作为异步进程运行。查看 github 上的黄油刀库。

牛油刀

您可以创建接口,将其传递给 AsyncTask(在构造函数中),然后在 onPostExecute 中调用方法

例如:

你的界面:

public interface OnTaskCompleted{
    void onTaskCompleted();
}

您的活动:

public YourActivity implements OnTaskCompleted{
    //your Activity
}

还有你的 AsyncTask:

public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
    private OnTaskCompleted listener;

    public YourTask(OnTaskCompleted listener){
        this.listener=listener;
    }

    //required methods

    protected void onPostExecute(Object o){
        //your stuff
        listener.onTaskCompleted();
    }
}
于 2013-10-22T14:11:26.830 回答
6

如果 Async 任务需要花费大量时间(通常是这样),则不应使用 .get() 。

相反,您可以使用消息/处理程序/服务/等,也可以简单地使用 onPostExecute(Result) 方法。

编辑:新代码。根据您的描述,您似乎需要使用接口。

如果您需要在另一个类中拥有 Asynctask,那么接口可能是您的最佳选择。

TestTask.java (您单独的 Asynctask):

import android.os.AsyncTask;

// Remember to change object type <> to what you need
public class TestTask extends AsyncTask<Object,Object,Object> {

    public interface OnTaskCompleted{
        void onTaskCompleted();
    }

    private OnTaskCompleted listener;

    public TestTask(OnTaskCompleted listener){
        this.listener = listener;
    }

    protected void onPostExecute(Object o){
        // Call the interface method
        if (listener != null)
            listener.onTaskCompleted();
    }

    @Override
    protected Object doInBackground(Object... params) {
        // The sleep() is just to simulate activity and delay
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

MainActivity.java(或任何其他活动):

public class MainActivity extends Activity {

private boolean status = false;

private OnTaskCompleted listener = new OnTaskCompleted() {
    public void onTaskCompleted() {
        status = true;
        Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
    new TestTask(listener).execute("Testing");
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}
于 2013-10-22T14:18:06.930 回答
1

我不喜欢在单独的类中执行 AsycTask 任务,尤其是在您需要使用响应的情况下。考虑到作为内部类实现时的容易程度,它使得与响应和局部变量的交互变得过于困难。

我猜你把它放在自己的类中,这样你就可以重用它。我会考虑将 AsycTask 保留为内部类,并在 doInBackground() 中调用外部可重用对象/方法。这将使代码保持干燥并允许您的活动对响应进行所需的操作。

public class MyActivity extends Activity {
    TextView textview;

    //...

    private class GetUrlTask extends AsyncTask<String, Integer, String> {

        protected String doInBackground(String... params) {
            return new GetHttpResponse().get(params[0]);
        }

        protected void onPostExecute(String response) {
            //Do UI updates...
            textview.setText(response);
        }
    }
}


public class GetHttpResponse {

    public String get(String url) {
        try {
            util = new HttpUtils(url);
            response = util.getContent();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    return response;
    }
}
于 2013-10-23T02:09:14.357 回答
0

你可以这样做:

public class MyActivity extends Activity
{
  public void someMethod()
  {
    // Here you could put up a ProgressDialog

    GetUrlDataTask myTask = new GetUrlDataTask();
    myTask.execute();
  }

  public class GetUrlDataTask extends AsyncTask<String, Integer, String>
  {
    @Override
    protected String doInBackground(String... params)
    {
      String response = null;
      HttpUtils util;

      try
      {
        util = new HttpUtils(params[0]);
        response = util.getContent();
      }
      catch (Exception e)
      {
        e.printStackTrace();
        response = e.getMessage();
      }
      return response;
    }

    @Override
    protected void onPostExecute(String result)
    {
      // Here you can dismiss the ProgressDialog and display the result
    }
  }
}
于 2013-10-22T14:27:52.763 回答