不使用get()方法从AsyncTask返回值

时间:2013-10-22 14:07:01

标签: android http android-asynctask

我正在尝试从DoInBackground中的asynctask返回值,但调用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 个答案:

答案 0 :(得分:10)

[更新]现在我建议使用注释。使用注释,您可以注入视图,只需几个字母就可以在编译步骤中将函数作为异步过程。查看github上的butterknife库。

ButterKnife

您可以创建接口,将其传递给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();
    }
}

答案 1 :(得分:6)

如果异步任务需要花费任何相当长的时间(通常是这样),则不应使用.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;
}

}

答案 2 :(得分:1)

我不喜欢在单独的类中使用AsycTask任务,特别是如果你需要使用响应。考虑到作为内部类实现它是多么容易,它使得与响应和局部变量的交互过于困难。

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

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

答案 3 :(得分: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
    }
  }
}