Android - AsyncTask 没有返回到主 Activity 的结果

标签 android thread-safety android-asynctask

我正在尝试使用 AsyncTask 扩展类来处理连接到 URL、解析 JSON、在解析过程中显示不确定的 ProgressDialog,以及将结果作为 HashMap 中的键值对返回到主 Activity。 HashMap 的结果将由主 Activity 读取并放入表单字段中。但是,即使我在我的 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);
            }
        });

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

}

最佳答案

当您发出以线程方式运行且不等待结果的 .execute() 时。

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

您需要通过 setter MainActivity.this.setProductInfo(result)

在 PostExecuted 上将结果直接设置到您的 Activity

关于Android - AsyncTask 没有返回到主 Activity 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4332710/

相关文章:

java - 线程安全的类和对象

android - 如何强制 PreferenceActivity 处理我的 SharedPreferences?

android - Fragment 中的 Listview 导致内存泄漏

android - Kotlin + Dagger 2 : cannot be provided without an @Provides-annotated method

java - 使用 java DocumentBuilder 从 xml feed 获取 rel ="alternate"href 值

rust - 将切片从静态回调转发到 channel 时存在冲突的生命周期要求

c++ - std::shared_ptr 在线程中使用时崩溃

java - Android加载图片到ListView AsyncTask

android - 调用 setAdapter 后 ArrayList 值消失

带有 ArrayAdapter 的 Android AsyncTask 给出错误 "Cannot resolve constructor"