Android:UI线程和其他线程之间的通信和协调

时间:2013-02-06 16:32:59

标签: android multithreading android-activity android-asynctask

我正在使用此AsyncTask来调用skype页面https://login.skype.com/json/validator?new_username=username,以了解某个Skype联系人是否已经存在。

public class SkypeValidateUserTask extends AsyncTask<String, Void, String>{

protected String doInBackground(String...urls){
    String response = "";
    for(String url:urls){
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        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 ex){
            ex.printStackTrace();
        }
    }
    return response;
}

public void onPostExecute(String result){
    String status="";
    try{    
        JSONObject obj=new JSONObject(result);
        status=obj.getString("status");
    }catch(Exception ex){
        ex.printStackTrace();
    }
    //Log.i("RISULTATO: ","STATO: "+status);

}
}

主要活动调用此任务以获取Skype验证用户结果。代码是:

String skype = "name.surname.example";  

if(!skype.equalsIgnoreCase("")){
            // check if the skype contact exists
            SkypeValidateUserTask task = new SkypeValidateUserTask();
            task.execute(new String[] {"https://login.skype.com/json/validator?new_username="+skype});  

                // here I need to obtain the result of the thread

        }

我的问题是:

  1. 我需要在主要活动中获得任务的结果(字符串status)。

  2. task.execute调用之后,执行main活动中的下一个代码而不等待asynctask返回的结果。

7 个答案:

答案 0 :(得分:2)

使用get()方法从异步任务获取结果是非常有用的,因为它会阻止UI线程。 使用此线程,我提供了一个可重用的解决方案Callback mechanism to get result from async thread without blocking UI Thread

我在lapslaz

的帮助下实现了这一点
public JsonData(YourActivityClass activity) 
{
    this.activity=activity;
    mProgressDialog = new ProgressDialog(activity);

}
protected void onPostExecute(String jsondata) {
    if (mProgressDialog != null || mProgressDialog.isShowing()){
        mProgressDialog.dismiss();
    }
    if(jsondata!=null) {
        activity.yourcallback(jsondata)
    }

}

And define the yourcallback() in YourActivityClass

private void yourcallback(String data) {
    jsonRecordsData=data;
    showRecordsFromJson();

}

答案 1 :(得分:1)

在主线程上启动AsyncTask。在AsyncTask的 preExecute 方法中,您可以启动ProgressDialog以向用户指示您正在执行需要几秒钟的操作。使用 doInBackground 执行长时间运行的任务(在您的情况下检查有效的Skype用户名)。完成后,将调用 onPostExecute 。由于这在UI线程上运行,因此您可以处理结果并根据它执行进一步的操作。不要忘记在onPostExecute中关闭ProgressDialog。

答案 2 :(得分:0)

这就是asyncTask在这里的原因。您无法在UI线程中进行阻止函数调用,因为这会使您的应用无响应。

答案 3 :(得分:0)

UI / Main 主题上调用

OnPostExcute 方法。你需要在那里移动逻辑以继续分析结果。

答案 4 :(得分:0)

如果您的AsyncTask是主要活动的内部类,那么您只需在主要活动中调用一个函数并将其传递给result

由于它看起来不是,您可以在Async中创建构造函数并将其从主活动传递给Context,以便将变量传递回主要活动

此外,AyncTask的目的是不阻止您的UI主题,将您的逻辑放在AsyncTask将调用的单独函数中

答案 5 :(得分:0)

您需要在AsyncTask中实现回调机制。所以不要这样:

task.execute(...);
// use results of task

你的结构应该是:

    task.execute(...);
    // go do something else while task has a chance to execute

public void statusAvailable(String status) {
    // use results of task
}

onPostExecute

public void onPostExecute(String result) {
    . . .
    status=obj.getString("status");
    activity.statusAvailable(status);
}

答案 6 :(得分:0)

从AsyncTask中获取结果很简单。 。 。只是谷歌文档没有说明如何做到这一点。这是一个快速下来。

task.execute(params);

将启动AsyncTask并将doInBackground方法传递给您包含的任何参数。 doInBackground完成后,会将其函数的结果传递给onPostExecute。有人会认为onPostExecute只能返回你发送的任何内容。它没有。要获得发送到doInBackground的{​​{1}}的结果,您需要致电

onPostExecute

task.get(); 方法自动等待,直到任务完成执行,然后将.get()的结果返回给UI线程。您可以将结果分配给您想要的任何变量,然后在此之后正常使用 - 例如

onPostExecute

换句话说 - 就像AsynTask不能自己启动一样,它不会自行返回。从UI线程需要JSONObject skypeStuff = task.get() 的方式,您需要从UI线程调用.execute()来提取任务的结果。