Android - AsyncTask的结果未返回到主Activity

Kee*_*13r 9 android thread-safety android-asynctask

我正在尝试使用AsyncTask扩展类来处理连接到URL,解析JSON,在解析期间显示不确定的ProgressDialog,以及将结果作为HashMap中的键值对返回到主Activity.然后,主Activity将读取HashMap的结果并将其放入表单字段中.但是,即使我在AsyncTask中填充HashMap(由println语句证明),在主Activity中调用返回HashMap的方法也会产生空结果.我无法弄清楚这是否是我做错了,或者我是否误解了AsyncTask的功能.

我正在辩论将我的类转换为将AsyncTask扩展为Activity.本质上,用户在此数据搜索/解析期间不应该执行任何其他操作,并且应该等到ProgressDialog消失之后才能再次与应用程序交互(或者通过按下后退按钮).此外,我的应用程序需要能够处理异常被捕获的AsyncTask中的某些情况(无法连接到URL,错误的JSON,无法找到要搜索的产品ID),并且针对这些异常定制了自定义错误对话框.如果这个类是一个Activity,我可以很容易地做到这一点,因为我可以在调用finish()时发回不同的结果代码,具体取决于是否捕获到异常.

同样,我不确定AsyncTask是否是最好的解决方案,因为在收集和解析信息时用户不会做任何其他事情.请告诉我一个新的Activity是否有意义,或者我是否只是修改了后台线程的实现.

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);
            }
        });
Run Code Online (Sandbox Code Playgroud)

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

Pen*_*m10 5

当您发出.execute()以线程运行并且不等待结果的情况时.

因此,无论您在此之后调用它,都是空的,因为尚未加载数据.

您需要通过setter将PostExecuted结果直接设置到您的Activity MainActivity.this.setProductInfo(result)

  • 在MainActivity中创建AsyncTask作为子私有类. (2认同)