2012-05-19 55 views
0

我正在开发Android中的应用程序。应用程序可以向特定的Web服务器发布HTTP请求。该发布请求必须异步运行,因此我创建了一个线程来完成这项工作。但是我需要一个将在线程结束时调用的回调函数,并且它必须从调用`post`方法的线程调用。Android:从特定线程执行方法

post方法是这样的:

interface EndCallback 
{ 
    public void Success(String response); 
    public void Fail(Exception e); 
} 

public void post(final String url, final List<NameValuePair> data, EndCallback callback) 
{ 
    Thread t = Thread.currentThread(); 
    (new Thread() 
    { 
     public void run() 
     { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost(url); 
      try 
      { 
       httppost.setEntity(new UrlEncodedFormEntity(data)); 
       HttpResponse r = httpclient.execute(httppost); 

       HttpEntity en = r.getEntity(); 
       String response = EntityUtils.toString(en); 

       //I want to call callback.Success(response) 
       //here from thread t 
      } 
      catch (Exception ex) 
      { 
       //And I want to call callback.Fail(ex) 
       //here from thread t 
      } 
     } 
    }).start(); 
} 
+0

查看[无痛线程](http://developer.android.com/resources/articles/painless-threading.html)了解许多选项,包括Handler,AsyncTask或将Runnable实例发布到活动或视图。 –

回答

1

创建新主题的Android是高度气馁于大多数应用。这似乎是AsyncTask的理想场所。它具有在线程之间切换的内置方法,无需手动管理线程创建。我已经在类似的情况下使用

一种方法是在任务有可能成功的美国enum结合:

class HttpPostTask extends AsyncTask<Void, Void, ResponseStatus> { 

    @Override 
    protected ResponseStatus doInBackground(Void... params){ 

     try { 
      // do your HTTP stuff 
      return ResponseStatus.SUCCESS; 
     } catch(Exception e){ 
      return ResponseStatus.FAILURE; 
     } 

    } 

    @Override 
    protected void onPostExecute(ResponseStatus status){ 
     switch(status){ 
     case SUCCESS: 
      // run your success callback 
      break; 
     case FAILURE: 
      // run the failure callback 
      break; 
     } 
    } 

} 

enum ResponseStatus { 
    SUCCESS, 
    FAILURE 
} 

doInBackground方法将在一个单独的线程中运行,由操作系统管理。当该线程完成时,onPostExecute将在启动任务的线程上运行,该任务通常是UI线程。

如果您需要设置回调对象,只需向HttpPostTask添加一个构造函数并执行所需的任何初始化。然后,您的客户端代码将只需要创建和执行任务:

new HttpPostTask().execute(); 

您也可以参数传递到​​为好,这接受可变数量的类签名的第一个通用类型的参数。 doInBackground中的params变量是传递给execute的所有相同类型的数组。

将参数传递到execute非常有用,例如,如果您想要发布到多个URL。对于大多数依赖项,在构造函数中设置它们是最简单的方法。

+0

完美答案......但是,我可以将参数传递给'execute()'方法吗?或者我必须将这些参数传递给构造函数? –

+1

@NiyokoYuliawan - 是的,我刚刚更新了答案的结尾。 – derekerdmann

2

您可能需要使用一个处理程序。处理程序用于向GUI线程发送请求。

成功处理,使用下面的代码:

final Handler successHandler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message message) 
    { 
     callback.Success(response); 
    } 
}; 

successHandler.sendEmptyMessage(0);