向 ui 发送回调的 android 异步任务

我有以下的异步任务类,它不在活动中。在活动中,我正在初始化异步任务,我希望异步任务向我的活动报告回调。 是否可能? 或者异步任务必须与活动在同一个类文件中?

protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
caller.sometextfield.setText("bla");
}

像这样吗?

144307 次浏览

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

例如:

你的界面:

public interface OnTaskCompleted{
void onTaskCompleted();
}

活动内容:

public class YourActivity implements OnTaskCompleted{
// your Activity
}

还有你的异步任务:

public class 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();
}
}

剪辑

由于这个答案很受欢迎,我想补充一些东西。

如果你是 Android 开发的新手,那么 AsyncTask是一种不用阻塞 UI 线程就能快速工作的方法。它确实解决了一些问题,这个类的工作方式本身并没有什么问题。然而,它带来了一些影响,例如:

  • 内存泄漏的可能性。如果您保持引用您的 Activity,它将留在内存中,甚至在用户离开屏幕(或旋转设备)。
  • 如果 Activity已被破坏,则 AsyncTask不会将结果传递给 Activity。您必须添加额外的代码来管理所有这些东西,或者执行两次操作。
  • Activity中做所有事情的复杂代码

当你觉得自己已经足够成熟,可以继续使用 Android 时,看看 这篇文章,我认为它是开发具有异步操作的 Android 应用程序的更好方法。

在完成上面的答案之后,您还可以为每个异步调用自定义备份,这样对通用 ASYNC 方法的每个调用将填充不同的数据,这取决于您放在那里的 onTaskdone 内容。

  Main.FragmentCallback FC= new  Main.FragmentCallback(){
@Override
public void onTaskDone(String results) {


localText.setText(results); //example TextView
}
};


new API_CALL(this.getApplicationContext(), "GET",FC).execute("&Books=" + Main.Books + "&args=" + profile_id);

提醒: 我在“ Main”出现的主活动上使用了接口,像这样:

public interface FragmentCallback {
public void onTaskDone(String results);




}

我的 API post 执行如下:

  @Override
protected void onPostExecute(String results) {


Log.i("TASK Result", results);
mFragmentCallback.onTaskDone(results);


}

API 构造函数如下所示:

 class  API_CALL extends AsyncTask<String,Void,String>  {


private Main.FragmentCallback mFragmentCallback;
private Context act;
private String method;




public API_CALL(Context ctx, String api_method,Main.FragmentCallback fragmentCallback) {
act=ctx;
method=api_method;
mFragmentCallback = fragmentCallback;




}

我觉得下面的方法很简单。

我已经为回调声明了一个接口

public interface AsyncResponse {
void processFinish(Object output);
}

然后创建异步任务来响应所有类型的并行请求

 public class MyAsyncTask extends AsyncTask<Object, Object, Object> {


public AsyncResponse delegate = null;//Call back interface


public MyAsyncTask(AsyncResponse asyncResponse) {
delegate = asyncResponse;//Assigning call back interfacethrough constructor
}


@Override
protected Object doInBackground(Object... params) {


//My Background tasks are written here


return {resutl Object}


}


@Override
protected void onPostExecute(Object result) {
delegate.processFinish(result);
}


}

然后在单击活动 Class 中的按钮时调用异步任务。

public class MainActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {


Button mbtnPress = (Button) findViewById(R.id.btnPress);


mbtnPress.setOnClickListener(new View.OnClickListener() {


@Override
public void onClick(View v) {


MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {


@Override
public void processFinish(Object output) {
Log.d("Response From Asynchronous task:", (String) output);
mbtnPress.setText((String) output);
}
});
asyncTask.execute(new Object[] { "Youe request to aynchronous task class is giving here.." });


}
});
}
}

谢谢

我会重复其他人说过的话,但会尽量简化..。

首先,只需创建 Interface 类

public interface PostTaskListener<K> {
// K is the type of the result object of the async task
void onPostTask(K result);
}

其次,通过包含一个具体的类,创建使用 Interface 的 AsyncTask (它可以是活动或片段的内部静态类)。在该示例中,PostTaskListener 使用 String 参数化,这意味着它需要一个 String 类作为异步任务的结果。

public static class LoadData extends AsyncTask<Void, Void, String> {


private PostTaskListener<String> postTaskListener;


protected LoadData(PostTaskListener<String> postTaskListener){
this.postTaskListener = postTaskListener;
}


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


if (result != null && postTaskListener != null)
postTaskListener.onPostTask(result);
}
}

最后,把你的逻辑结合起来。在活动/片段中,创建 PostTaskListener 并将其传递给异步任务。这里有一个例子:

...
PostTaskListener<String> postTaskListener = new PostTaskListener<String>() {
@Override
public void onPostTask(String result) {
//Your post execution task code
}
}


// Create the async task and pass it the post task listener.
new LoadData(postTaskListener);

成交!