从没有 get() 方法的 AsyncTask 返回值



我正在尝试从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;

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

主活动.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;
}
}

我不太喜欢将 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;
    }
}

你可以做这样的事情:

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

最新更新