如何从异步任务中返回结果

5

我一直在使用异步任务来访问Web服务器并使用结果更新控件。这样做有缺点,即使异步方法特定于控件,也会阻止我再次使用返回的字符串。

如何从onPostExecute中返回异步调用的结果字符串?我该如何调用它?我似乎无法让我的代码实现这一点。由于我有一个对话框可以冻结UI直到工作完成,因此应该不会出现线程问题。

我的典型异步任务代码如下:

class GetDataFromServer extends AsyncTask<String, String, String>
{
     * */
    // Progress Dialog
    private ProgressDialog qDialog;
    private Context context;
    private String dialogString;
    private ArrayList<String[]> newLoginResult;

    // JSON parser class
    String url_newGame ="http://xxxxxx.php";

    public myAsyncMethos(String dialogMessage, Context con)
    {
        this.qDialog =  new ProgressDialog(con);
        this.dialogString = dialogMessage;
        this.context = con;
    }

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        qDialog = new ProgressDialog(this.context);
        qDialog.setMessage(this.dialogString);
        qDialog.setIndeterminate(false);
        qDialog.setCancelable(false);
        qDialog.show();
    }

    @Override
    protected JSONObject doInBackground(String... args)
    {
        //MAKE SERVER CALL and cast to JSONOBject

        return jsonNewUser;
    }

    public void onPostExecute(JSONObject jsonString)
    {

         // dismiss the dialog after getting response
        qDialog.dismiss();
//I WANT TO RETURN A STRING HERE BUT KEEP GETTING SYNTAX ERRORS BEFORE RUNTIME


    }
}

1
https://dev59.com/2GQn5IYBdhLWcg3wiXmd - Blackbelt
4个回答

4

我个人建议给你的类添加一个回调函数,然后一旦 onPostExecute 运行,就触发回调函数,将结果传递给主类的监听器。

class GetDataFromServer extends AsyncTask<String, String,JSONObject>
{
    // Progress Dialog
    private ProgressDialog qDialog;
    private Context context;
    private String dialogString;
    private ArrayList<String[]> newLoginResult;
    private InformComplete myCallback;

    public GetDataFromServer(String dialogMessage, Context con,InformComplete callback)
    {
        this.qDialog =  new ProgressDialog(con);
        this.dialogString = dialogMessage;
        this.context = con;
        this.myCallback=callback;
    }

    @Override
    protected void onPreExecute()
    {
        // set up your dialog
    }

    @Override
    protected JSONObject doInBackground(String... args)
    {
        JSONObject jsonNewUser=new JSONObject();
        return jsonNewUser;
    }

    public void onPostExecute(JSONObject jsonString)
    {
        qDialog.dismiss();
        myCallback.PostData(jsonString);
    }
    public interface InformComplete
    {
        public void PostData(JSONObject result);
    }
}

然后在您的调用类中,您可能会有以下内容...

    private void callTheAsyncThing
    {
        GetDataFromServer gds=new GetDataFromServer("please wait", this, letMeKnow);
        gds.execute(params);
    }

    private InformComplete letMeKnow=new InformComplete()
    {
        public void PostData(JSONObject result)
        {
            // we now have the data in the calling class
        }
    };

你能给我一些框架代码来演示一下吗?我不是100%确定如何做。 - Fearghal
我已经创建了骨架代码来实现这个 - 请点击此处查看 - Ed Holloway-George
我已经编辑了我的答案,给你一个例子。 - Rich S
谢谢,比如说,我在主活动中检索数据的调用代码是什么? - Fearghal
编辑我的答案以反映这一点。 - Rich S
几乎一样,只是我实现了一个接口,请看我的添加的答案。 - Fearghal

1
由于AsyncTask中使用的是void元素,所以无法在方法中返回值。因此,您可以实例化全局变量,并将其值设置为该变量。例如:`
class GetDataFromServer extends AsyncTask<String, String, String>
{
     * */
    // Progress Dialog
    private ProgressDialog qDialog;
    private Context context;
    private String dialogString;
    private ArrayList<String[]> newLoginResult;
    private String value;

    // JSON parser class
    String url_newGame ="http://xxxxxx.php";

    public myAsyncMethos(String dialogMessage, Context con)
    {
        this.qDialog =  new ProgressDialog(con);
        this.dialogString = dialogMessage;
        this.context = con;
    }

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        qDialog = new ProgressDialog(this.context);
        qDialog.setMessage(this.dialogString);
        qDialog.setIndeterminate(false);
        qDialog.setCancelable(false);
        qDialog.show();
    }

    @Override
    protected JSONObject doInBackground(String... args)
    {
        //MAKE SERVER CALL and cast to JSONOBject

        return jsonNewUser;
    }

    public void onPostExecute(JSONObject jsonString)
    {

         // dismiss the dialog after getting response
        qDialog.dismiss();
        value = "Whatever you want";
    }
    public void setValue(String value){
         this.value=value;
    }
    public String getValue(){
         return this.value;
    }
}`

然后使用它。有一种方法可以返回某些东西。顺便说一下,您无法更改返回值。


那个变量不是全局的,对吧?它不能从其他类中访问,对吗? - Fearghal
不是100%“全局”的,我很抱歉。当我说“全局”时,我想说的是在同一类中的其他方法中。就像你所说的那样,全局是公共的,无论类在哪里。如果在同一个包中,则为受保护的。私有只有同一类。实际上,应该为该变量编写getter和setter以设置和获取值。我没有在此示例中输入它,因为通常会生成pojo类。 - Jnmgr
我已经编辑过了,展示了如何编写setter和getter方法;正如我所说的那样,这应该在POJO类中完成,而不是在同一个类中。实际上,如果你想要做到“纯粹”,创建另一个带有AyncTask的类是最好的方式。 - Jnmgr

0

onPostExecute方法不是由程序员调用的,而是由AsyncTask实例调用的。如果您想从异步任务中返回结果,可以将参数发送到GetDataFromServer中,在onPostExecute方法中给它赋新值,然后使用Handler发送消息。


-1
在 doInBackground 方法中返回 JSONObject,而在 onPostExecute 方法中尝试获取字符串。
public void onPostExecute(JsonObject jsonString)
{
     // dismiss the dialog after getting response
     qDialog.dismiss();
     //I WANT TO RETURN A STRING HERE BUT KEEP GETTING SYNTAX ERRORS BEFORE RUNTIME
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接