Android的 - 从AsyncTask的结果在返回的主要活动 [英] Android - result from AsyncTask not being returned to main Activity

查看:118
本文介绍了Android的 - 从AsyncTask的结果在返回的主要活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用一个AsyncTask的扩展类来处理连接到一个URL,JSON解析,解析过程中显示一个不确定的ProgressDialog,并返回结果键 - 值对在HashMap的主要活动。 HashMap中的结果将随后由主要活动被读取并投入表单域。然而,即使我填充的HashMap在我的AsyncTask(通过println语句证明),调用返回HashMap中产生一个空结果的主要活动的方法。我想不通,如果这是我做错了,或者如果我误解的AsyncTask的能力。

我辩论转换我的课延伸到AsyncTask的一个活动。从本质上讲,用户不应该能够在这个数据的搜索/解析过程中做任何事情,应该等到ProgressDialog消失,才可以与应用程序交互再次(或者点击后退按钮)。另外,我的应用程序需要能够处理这样的情况,我的AsyncTask那里异常被捕获(无法连接到URL,不良JSON,产品ID由无法找到搜索)和自定义错误对话框是专为那些异常。我可以很容易地做到这一点,如果这个类是活动,如调用结束时(我可以发送回不同的结果codeS),这取决于如果一个异常被捕获。

同样,我不知道的AsyncTask是最好的解决方案在这里,因为当信息被收集和分析用户不会做别的。请告诉我,如果一个新的活动是有意义的,或者如果我只是在我的压延执行后台线程的。

MainActivity.java

  mInitiateProductLookupButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图v){
                ProductLookup PL =新ProductLookup(ID,MainActivity.this);
                pl.execute();                //以下变量始终是空的!
                HashMap的<字符串,字符串> productInfo = pl.getProductInfo();
                applyProductInfoToFormFields(productInfo);
            }
        });

ProductLookup.java

 公共类ProductLookup扩展的AsyncTask<对象,无效的HashMap<字符串,字符串>> {
    私人字符串mProductID;
    私人语境mContext;
    HashMap的<字符串,字符串> mProductInfo;
    ProgressDialog支持mDialog;    公共ProductLookup(字符串ID,上下文的applicationContext){
        mProductID = ID;
        mContext =的applicationContext;
        mProductInfo =新的HashMap<字符串,字符串>();
    }    @覆盖
    在preExecute保护无效(){
        支持mDialog =新ProgressDialog(mContext);
        mDialog.setMessage(加载产品信息请稍候......);
        mDialog.setIndeterminate(真);
        mDialog.setCancelable(假);
        mDialog.show();
    }    @覆盖
    保护无效onPostExecute(HashMap的<字符串,字符串>的结果){
       super.onPostExecute(结果);
       mDialog.dismiss();
       mProductInfo =结果;
    }
    @覆盖
    保护的HashMap<字符串,字符串> doInBackground(对象... PARAMS){
        尝试{
            //连接到URL,解析JSON,并添加键值对,以mProductInfo ...        }赶上(MalformedURLException的E){
            e.printStackTrace();
        }赶上(IOException异常五){
            e.printStackTrace();
        }赶上(JSONException E){
            e.printStackTrace();
        }
        最后{
            尝试{
                //关闭输入/输出变量的读者
            }赶上(IOException异常五){
                e.printStackTrace();
            }
        }
        返回mProductInfo;    }    公众的HashMap<字符串,字符串> getProductInfo(){
        返回this.mProductInfo;
    }}


解决方案

当你发出 .execute()运行的线程,不等待结果。

所以,你这后打电话什么的,因为数据尚未加载的是空的。

您需要在PostExecuted结果直接通过一个se​​tter设置为您的活动 MainActivity.this.setProductInfo(结果)

I'm trying to use an AsyncTask-extended class to handle connecting to a URL, parsing JSON, displaying an indeterminate ProgressDialog during parsing, and returning the results as key-value pairs in a HashMap to the main Activity. The results of the HashMap will then be read by the main Activity and put into form fields. However, even though I'm populating the HashMap in my AsyncTask (evidenced by println statements), calling a method in the main Activity that returns the HashMap yields an empty result. I can't figure out if this is something I'm doing wrong, or if I'm misunderstanding the capabilities of AsyncTask.

I'm debating converting my class that extends AsyncTask to an Activity. Essentially, the user should not be able to do anything else during this data search/parsing and should wait until the ProgressDialog goes away before they can interact with the application again (or by hitting the back button). Also, my application needs to be able to handle certain cases in my AsyncTask where exceptions are caught (can't connect to URL, bad JSON, product ID to search by cannot be found) and custom error dialogs are tailored for those exceptions. I could easily do this if this class were an Activity, as I could send back different result codes when calling finish(), depending on if an exception is caught.

Again, I'm not sure if AsyncTask is the best solution here, since the user will not be doing anything else while the information is being gathered and parsed. Please advise me if a new Activity would make sense or if I'm just mangling my implementation of a background thread.

MainActivity.java

mInitiateProductLookupButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                ProductLookup pl = new ProductLookup(id, MainActivity.this);
                pl.execute();

                // The below variable is always empty!
                HashMap<String, String> productInfo = pl.getProductInfo();
                applyProductInfoToFormFields(productInfo);
            }
        });

ProductLookup.java

public class ProductLookup extends AsyncTask<Object, Void, HashMap<String, String>> {
    private String mProductID;
    private Context mContext;
    HashMap<String, String> mProductInfo;
    ProgressDialog mDialog;

    public ProductLookup(String id, Context applicationContext) {
        mProductID = id;
        mContext = applicationContext;
        mProductInfo = new HashMap<String, String>();
    }

    @Override
    protected void onPreExecute() {
        mDialog = new ProgressDialog(mContext);
        mDialog.setMessage("Loading product info. Please wait...");
        mDialog.setIndeterminate(true);
        mDialog.setCancelable(false);
        mDialog.show();
    }

    @Override
    protected void onPostExecute(HashMap<String, String> result){
       super.onPostExecute(result);
       mDialog.dismiss();
       mProductInfo = result;
    }


    @Override
    protected HashMap<String, String> doInBackground(Object... params) {
        try {
            // Connect to URL, parse JSON, and add key-value pairs to mProductInfo...

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        finally {
            try {
                // Close input/output reader variables
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return mProductInfo;

    }

    public HashMap<String, String> getProductInfo(){
        return this.mProductInfo;
    }

}

解决方案

When you issue .execute() that runs as threaded and doesn't wait for the result.

So whatever you call after this it, is empty as the data has not been loaded yet.

You need to set on PostExecuted the result directly to your Activity via a setter MainActivity.this.setProductInfo(result)

这篇关于Android的 - 从AsyncTask的结果在返回的主要活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆