android - AsyncTask fragment 轮换

标签 android multithreading rotation

我在显示天气数据(图像、温度和天气描述)的 fragment 中有一个 ListView 。我从 here 获取数据

当我旋转模拟器时,虽然我遇到了崩溃。:(。这是我的代码。我使用 setRetainedInstance 但没有任何结果。我需要以某种方式保存和恢复我获得的异步数据,但我没有知道怎么做。

    public class ForecastFragment extends Fragment{

    ListView listView;
    List<WeatherForecastData> WeatherForecastDataList;
    String IMG_URL = "http://api.openweathermap.org/img/w/";
    Fragment fragment;
    public ForecastFragment() {
        // Required empty public constructor
    }

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    //Inflate xml view and convert it to a View object
    View rootView = inflater.inflate(R.layout.fragment_forecast, container, false);

    //Initialise ListView.
    listView = (ListView) rootView.findViewById(R.id.listView);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String temp = WeatherForecastDataList.get(position).getWeatherTemperature();

            Toast.makeText(getActivity(),temp+" Have a nice day",Toast.LENGTH_SHORT).show();
        }
    });
    return rootView;
}

    //Now we are ready for further processing
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    setRetainInstance(true);

    requestData("http://api.openweathermap.org/data/2.5/forecast/daily?lat=50.09&lon=14.42&cnt=9&&units=metric&mode=json");

}
//We create a MyTask object,and execute the async. thread with the specified url which is shown just above.
private void requestData(String uri) {
    MyTask task = new MyTask();
    task.execute(uri);
}
//AsyncTask that will do the asynchronous threading. It displays the weather's icon,description
//and temperature in the main thread via the OnPostExecute(...) method.
private class MyTask extends AsyncTask<String, String, List<WeatherForecastData>> {

    @Override
    protected void onPreExecute() {
        //Used to initialise Views such as Progress Bars which are not needed for this
        //project.
    }

    @Override
    protected List<WeatherForecastData> doInBackground(String... params) {
        //Read the url,specify the METHOD GET, and store it in content.
        String content = HttpManager.getData(params[0]);
        //JSON parsing of the openweather api's response. It is not hard,but I had to use the
        //debugger quite a lot to make sure that I deserialise the correct JSON values into Strings.
        WeatherForecastDataList = WeatherJSONParser.parseFeed(content);
        //Fetching the url image
        for (WeatherForecastData d : WeatherForecastDataList) {
            try {
                String imageUrl = IMG_URL +d.getPhoto();
                InputStream in = (InputStream) new URL(imageUrl).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                //Is it deprecated?
                d.setBitmap(bitmap);
                in.close();
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        return WeatherForecastDataList;
    }
    //WeatherForecastData is the Object that contains all that instances we want to display.
    @Override
    protected void onPostExecute(List<WeatherForecastData> result) {

        if (result == null) {
            Toast.makeText(getActivity(), "There is some wrong,and data can not be displayed", Toast.LENGTH_LONG).show();
            return;
        }
        WeatherForecastDataList = result;
        //Display the ListView.
        WeatherAdapter adapter = new WeatherAdapter(getActivity(), R.layout.weather_row,WeatherForecastDataList);
        listView.setAdapter(adapter);
    }

  }
}

这是我的日志。

08-01 19:45:59.857  21260-21260/com.theotziomakas.weatherapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
        at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:153)
        at com.theotziomakas.weatherapp.Fragments.WeatherAdapter.<init>(WeatherAdapter.java:34)
        at com.theotziomakas.weatherapp.Fragments.ForecastFragment$MyTask.onPostExecute(ForecastFragment.java:144)
        at com.theotziomakas.weatherapp.Fragments.ForecastFragment$MyTask.onPostExecute(ForecastFragment.java:98)
        at android.os.AsyncTask.finish(AsyncTask.java:631)
        at android.os.AsyncTask.access$600(AsyncTask.java:177)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4867)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
        at dalvik.system.NativeStart.main(Native Method)

最佳答案

你需要实现onSaveInstanceState来保存数据,然后在onCreateView中获取它

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString("YourVariableName", yourVariable);
    super.onSaveInstanceState(savedInstanceState);
}

然后在onCreateView

if (savedInstanceState != null) {
    yourVariable = savedInstanceState.getString("YourVariableName");
}

查看 documentation了解更多信息

关于android - AsyncTask fragment 轮换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31765122/

相关文章:

android - Android库项目中的数据封装

android - 如何在保持页面全宽的同时设置 ViewPager 页面之间的填充

android - 无法解析符号 'REQUEST_ENABLE_BLUETOOTH'

java - 线程池与许多单独的线程

java - java ScheduledExecutorService任务在多次执行后停止

iphone - GCD 获取队列名称/标签

java - 如何将私钥与证书链绑定(bind)?

java - IntervalMarker 的 JFreeChart 垂直标签

javafx - 如何将偏航、俯仰和滚动增量(不是欧拉)应用于相对于节点旋转轴而不是场景旋转轴的节点?

javascript - 将缩放和旋转应用于特定点 - Javascript