【问题标题】:Access Activity Method From AsyncTask Callback Interface从 AsyncTask 回调接口访问 Activity 方法
【发布时间】:2020-05-01 04:39:00
【问题描述】:

我有几个活动和一个 asyncTask 使用相同的接口用于回调方法,如下所示

大家使用的接口

public interface AsyncTaskCallback {
    void onCookie(CookieManager cookieManager);
    void onResponse(String response);
    void onProgress(String... values);
    void onError(Exception e);
}

AsyncTask1 从所有活动中调用如下

public void exec_taskt() {
   alertDialog.SetText("Sending Request...");
   AsyncTask1 task1 = new AsyncTask1("https://stackoverflow.com");
   task1.setCookieManager(cookiejar);
   task1.setCallback(this);
   task1.execute();
}

每个Activity也实现了接口

@Override
public void onCookie(CookieManager cookieManager) {
    cookiejar = cookieManager;
}

@Override
public void onResponse(String response) {
    try {
        PostProc(response);
    }catch (Exception e){ // ERROR HERE
        e.printStackTrace();
    }
}

@Override
public void onProgress(String... values) {
    alertDialog.SetText(values[0]);
}

@Override
public void onError(Exception e) {
    ///SAME ERROR HERE TOO
    //Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
    swipeRefreshLayout.setRefreshing(false);
}

private void PostProc(String response) {
    //the response string is parsed and displayed in a recyclerview in this method
    //this method is slightly different for each activity
}

异步任务1

public class AsyncTask1 extends AsyncTask<String, String, String> {
   private String address = "";
   private CookieManager mCookieManager;
   private Exception mException;
   private AsyncTaskCallback mCallback;


   public AsyncTask1 (String page) {
        this.address = page;

   }

   public void setCookieManager(CookieManager cm) {
    this.mCookieManager = cm;
   }

   public void setCallback(AsyncTaskCallback cb) {
     this.mCallback = (AsyncTaskCallback) cb;

   }

   @Override
protected String doInBackground(String... strings) {
  try{
        //all code here is executed without error 
        //code skipped for simplicity 
        // basically just loads the given url and then...
        publishProgress("Page Loaded");
        mCallback.onCookie(mCookieManager);
        mCallback.onResponse(response);

        return response;
  } catch (Exception e) {
        publishProgress("Error");
        e.printStackTrace();
        mCallback.onError(e);
        return "";
    }

 @Override
protected void onProgressUpdate(String... values) {
    Log.d(tag, TextUtils.join(",", values));
    mCallback.onProgress(values);
    super.onProgressUpdate(values);
}
}

我得到的错误被标记

这里有错误

在上面的代码中。消息如下

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我的主要怀疑是 Activity 中的 PostProc() 方法与 UI 组件一起使用。但是在activity中实现接口不就意味着部分代码在主UI线程中运行吗?我知道您可以将活动实例传递给 asyncTask 并从 asyncTask 的 postexecute 调用 PostProc() 方法,但我想探索一种替代方法,因为其他活动也可以访问相同的 asynctask。所有活动的回报都是一样的。只有PostProc方法不同。

提前致谢

【问题讨论】:

  • 但是在activity中实现接口不意味着部分代码运行在主UI线程中吗? no明显的选择是要么使用onPostExecute或将执行发布到 UI 线程
  • 我建议迁移到 RxJava 或 @Santanu Sur 答案。 AsyncTask 即将被弃用

标签: java android interface android-asynctask


【解决方案1】:

您可以使用与Looper.getMainLooper() 关联的android.os.Handler() 而不是使用callback interface 来更新视图,例如:-

AsyncTask1 task1 = new AsyncTask1(android.os.Handler(Looper.getMainLooper(),  msg -> { 
 // handle message sent from asyncTask
  return false;
}), url);

然后在task1 中使用处理程序发送消息

public AsyncTask1 (Handler handler, String page) {
    this.address = page;
    this.handler = handler;
}

那么,

Message message = new Message();
message.obj = uiData;
handler.sendMessage(message);

处理程序onHandleMessage 将始终在main looper 上执行!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    相关资源
    最近更新 更多