【问题标题】:Problem with returning object form a class extending AsyncTask从扩展 AsyncTask 的类返回对象的问题
【发布时间】:2019-06-21 13:18:44
【问题描述】:

我遇到了从扩展 AsyncTask 的类 HttpRequestCurrentWeather 返回对象的 getter 函数的问题。在此类中,我从 API 接收数据,并希望根据收到的内容在 CurrentWeatherFragment 中设置一些 TextView。问题是我无法将 DataModel 的整个对象返回到 Fragment 并在那里设置组件,也无法将 TextViews 设置为 onPostExecute() 方法,因为我得到了 NullPointerException ( java.lang.NullPointerException: Attempt to invoke virtual method ' android.view.View android.view.View.findViewById(int)' 在空对象引用上)。我应该如何设置这些 TextView?

public class CurrentWeatherFragment extends Fragment {
    DataModel dataModel = new DataModel();

    TextView tv_city;
    TextView tv_temperature;
    TextView tv_pressure;

    public void setComponents() {
        this.tv_city = getView().findViewById(R.id.tv_current_city_name);
        tv_city.setText(dataModel.getName());

        this.tv_temperature = getView().findViewById(R.id.tv_current_temperature);
        tv_temperature.setText(dataModel.getTemp());

        this.tv_pressure = getView().findViewById(R.id.tv_current_pressure);
        tv_pressure.setText(dataModel.getPressure());
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View RootView = inflater.inflate(R.layout.fragment_current_weather_layout, container, false);


        HttpRequestCurrentWeather httpRequestCurrentWeather1 = new HttpRequestCurrentWeather();
        httpRequestCurrentWeather1.execute("", "", "");

        // here I receive null object, but why?
        dataModel = httpRequestCurrentWeather1.getDataModel();

        // set the texts in components:
        setComponents();

        return RootView;
    }
}
public class HttpRequestCurrentWeather extends AsyncTask<String, Void, DataModel> {
        DataModel dataModel;

        public HttpRequestCurrentWeather() {
            this.dataModel = null;
        }

        @Override
        protected DataModel doInBackground(String... params) {
            ApiCurrentWeather apiCurrentWeather1 = new ApiCurrentWeather("London", "uk");

            try {
                // catch the model with recived data from API:
                dataModel = apiCurrentWeather1.getWeather();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return dataModel;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(DataModel dataModel) {
        super.onPostExecute(dataModel);

        CurrentWeatherFragment fragment = new CurrentWeatherFragment();

        TextView tv_temperature = (TextView)fragment.getView().findViewById(R.id.tv_current_temperature);
        tv_temperature.setText(dataModel.getTemp());

    }

    // this function returns NULL object ????
    public DataModel getDataModel(){
        return this.dataModel;
    }
}

【问题讨论】:

  • execute() 在后台线程上执行 AsyncTask 工作 (doInBackground()),因此在下一条语句中 dataModel 仍将是 null。你正在onPostExecute() 中创建一个全新的CurrentWeatherFragment(),它没有视图。 AsyncTask 本身已经很老了,不再那么流行了。您可能希望考虑更现代的技术(例如,ViewModelLiveData)。或者,您可以使用为您处理后台线程的 HTTP 客户端库(例如 OkHttp、Retrofit)。
  • 我知道这是很老的方式,但我真的很想知道如何做到这一点。那么,你有什么建议呢?
  • 我只需要从 HttpRequestCurrentWeather 类中提取这个 DataModel 对象......
  • “你有什么建议?” ——我已经给了你两个建议。让AsyncTask 正常工作并处理配置更改是相当复杂的。您需要设置一个单独的无头保留片段来执行AsyncTask 工作,然后弄清楚如何从该单独片段中获取结果到这个片段。或者,您需要非常小心CurrentWeatherFragment 设为保留片段。我不推荐其中任何一种。我建议您转向更现代的技术。
  • 是的,你是对的 - 使用 Retrofit 要简单得多!谢谢!

标签: java android android-fragments android-asynctask return


【解决方案1】:

说实话,这不是正确答案的样子,但是我尝试使用 AsyncTask 实现的目标似乎使用 Retrofit 更容易,所以我最终放弃了这个想法并决定改用 Retrofit 。如果你有类似的问题,忘记 AsyncTask - Retrofit 更适合这个!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多