【问题标题】:Android, can I put AsyncTask in a separate class and have a callback?Android,我可以将 AsyncTask 放在单独的类中并进行回调吗?
【发布时间】:2012-06-01 20:44:58
【问题描述】:

我只是在学习 AsyncTask,想将它用作一个单独的类,而不是一个子类。

例如,

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


    @Override
    protected String doInBackground(String... urls) {

        String response = "";

            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(urls[0]);
            try {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(
                        new InputStreamReader(content));
                String s = "";
                while ((s = buffer.readLine()) != null) {
                    response += s;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        return response;
    }


    @Override
    protected void onPostExecute(String result) {
        Log.e("xx",result);
        // how do I pass this result back to the thread, that created me?
    }


}

和主(ui)线程:

inetloader il = new inetloader();
il.execute("http://www.google.com");
//il.onResult()
//{
    ///do something...
//}

谢谢!

【问题讨论】:

  • 是的,你可以把它放在一个单独的类中,但大多数人不这样做,因为如果它是一个内部类,它的目的通常会更清楚。如果您要在很多活动中重复使用它,请继续。
  • 我计划将它用于不同的目的,比如如果我从这里调用它,结果它应该这样做,如果我从那里调用它,结果它应该做其他事情......因此,如果我将它保留在同一个类中并让它在结果上调用该类中的一个函数,我将不得不为它必须在结果上执行的每种操作创建一个新的 AsyncTask ...
  • 使用接口,只需通过一个接口实现你的activity,并在Asyn类的onPostExcute()中调用mContext.implementedMethod()。
  • 将它放在单独的类中也有助于版本控制和变更管理。
  • 顺便说一句,请以大写字母开头你的类名,例如“InetLoader”——只是基本的 Java 约定。

标签: java android android-asynctask


【解决方案1】:

使用接口。比如:

interface CallBackListener{
  public void callback();
}

然后在您的 UI 线程中执行此操作:

inetloader il = new inetloader();
li.setListener(this);
il.execute("http://www.google.com");

在inetloader中,添加:

   CallBackListener mListener;

   public void setListener(CallBackListener listener){
     mListener = listener;
   }

然后在 postExecute() 中,执行:

   mListener.callback();

【讨论】:

  • 谢谢,听起来这是正确的方向。特别是如果我可以使用 inetloader 创建一个 CallBackListener il = new inetloader();并将其传递给 il 对象。
  • 嗯...奇怪,我在 android v3 中没有“CallBackListener”,也许它有其他名称?
  • @RogerTravis 是的,你必须自己创建一个 CallBackListener 接口。并且不要忘记为您的主 UI 类添加“实现 CallBackLisnter”。
  • 哎呀,它似乎只给了一个 @Override public void callback() { 用于 UI 线程。有没有办法为我创建的每个 inetloader 对象创建多个回调(){}?
【解决方案2】:

您可以将活动实例传递给构造函数并从那里调用活动函数...
喜欢使用界面:

public interface ResultUpdatable {

   public void setResult(Object obj);
   }

在Activity中实现这个并传入异步任务的构造函数,并使用setResult函数从onPostExecute更新结果。

【讨论】:

    【解决方案3】:
    inetloader il = new inetloader();
    il.execute("http://www.google.com");
    
    String result = il.get();//put it in try-catch
                    ^^^^^^^^ 
    

    here you get result which is in onPostExecute(String result)

    【讨论】:

    • 不是真的 :( 我需要某种 onResult 侦听器,一旦 AsyncTask 完成就会触发,因为查询某些服务器可能需要一段时间。另一方面,将 il.get()进入 while(true) 循环可能听起来太原始了,不是吗?:) 有更好的选择吗?
    • @Samir :这是一个非常糟糕的主意。虽然它确实允许从AsyncTask 检索结果,但使用get() 方法将阻塞UI 线程并有效地将应该是异步过程的过程转换为同步过程。我曾经想出的get() 方法的唯一有效用途是“链接”两个AsyncTasks
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2018-08-08
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    相关资源
    最近更新 更多