Android 碎片旋转

Android 碎片旋转,android,rotation,Android,Rotation,我有下面的代码从OpenWeatherMapAPI检索一些天气数据。AsyncTask类用于此目的 public class ForecastFragment extends Fragment { String imageUrl; ListView listView; List<WeatherForecastData> WeatherForecastDataList; String IMG_URL = "http://api.openweathermap.org/img/w/"; F

我有下面的代码从OpenWeatherMapAPI检索一些天气数据。AsyncTask类用于此目的

public class ForecastFragment extends Fragment {
String imageUrl;
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 + "° C"+" 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);
    if (savedInstanceState == null) {
        if(isOnline()) {
            requestData("http://api.openweathermap.org/data/2.5/forecast/daily?lat=50.09&lon=14.42&cnt=9&&units=metric&mode=json");
        }else{
            Toast.makeText(getActivity(),"There is no internet connection",Toast.LENGTH_SHORT).show();
        }
    }

}

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

//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 {
                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);
    }

}

protected boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    } else {
        return false;
    }
}
}
公共类ForecastFragment扩展了片段{
字符串imageUrl;
列表视图列表视图;
天气预报数据表;
字符串IMG_URL=”http://api.openweathermap.org/img/w/";
片段;
公众预报员(){
//必需的空公共构造函数
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
//膨胀xml视图并将其转换为视图对象
视图根视图=充气机。充气(R.layout.fragment\u预测,容器,false);
//初始化ListView。
listView=(listView)rootView.findViewById(R.id.listView);
setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
字符串temp=WeatherForecastDataList.get(位置).getWeatherTemperature();
Toast.makeText(getActivity(),temp+“°C”+”祝您有一个愉快的一天“,Toast.LENGTH_SHORT).show();
}
});
返回rootView;
}
//现在我们已经准备好进行进一步处理
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
setRetainInstance(真);
如果(savedInstanceState==null){
if(isOnline()){
请求数据(“http://api.openweathermap.org/data/2.5/forecast/daily?lat=50.09&lon=14.42&cnt=9&&units=metric&mode=json");
}否则{
Toast.makeText(getActivity(),“没有internet连接”,Toast.LENGTH_SHORT.show();
}
}
}
@凌驾
SaveInstanceState上的公共无效(Bundle savedInstanceState){
savedInstanceState.putString(“ImageURL”,ImageURL);
super.onSaveInstanceState(savedInstanceState);
}
//我们创建一个MyTask对象,并使用上面显示的指定url执行async.thread。
私有void请求数据(字符串uri){
MyTask任务=新建MyTask();
task.execute(uri);
}
//将执行异步线程的AsyncTask。它显示天气图标,说明
//通过OnPostExecute(…)方法在主线程中设置温度。
私有类MyTask扩展了AsyncTask{
@凌驾
受保护的void onPreExecute(){
//用于初始化此操作不需要的视图,如进度条
//项目。
}
@凌驾
受保护列表doInBackground(字符串…参数){
//读取url,指定GET方法,并将其存储在内容中。
String content=HttpManager.getData(参数[0]);
//OpenWeatherAPI响应的JSON解析。这并不难,但我必须使用
//为了确保将正确的JSON值反序列化为字符串,调试程序进行了大量工作。
WeatherForecastDataList=WeatherJSONParser.parseFeed(内容);
//获取url图像
用于(WeatherForecastData d:WeatherForecastDataList){
试一试{
imageUrl=IMG_URL+d.getPhoto();
InputStream in=(InputStream)新URL(imageUrl).getContent();
位图位图=位图工厂.decodeStream(in);
//它被弃用了吗?
d、 setBitmap(位图);
in.close();
}捕获(例外e){
e、 printStackTrace();
}
}
返回天气预报数据表;
}
//WeatherForecastData是包含我们要显示的所有实例的对象。
@凌驾
受保护的void onPostExecute(列表结果){
如果(结果==null){
Toast.makeText(getActivity(),“有一些错误,无法显示数据”,Toast.LENGTH_LONG.show();
返回;
}
WeatherForecastDataList=结果;
//显示列表视图。
WeatherAdapter=新的WeatherAdapter(getActivity(),R.layout.weather_行,WeatherForecastDataList);
setAdapter(适配器);
}
}
受保护的布尔isOnline(){
ConnectivityManager cm=(ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_服务);
NetworkInfo netInfo=cm.getActiveNetworkInfo();
如果(netInfo!=null&&netInfo.isConnectedOrConnecting()){
返回true;
}否则{
返回false;
}
}
}

我的问题是如何使我的异步任务类在手机旋转时工作。换句话说,我不希望我的片段被杀死,而是存储我得到的天气信息。我在这里也看到了其他问题,但我对这一部分感到困惑。谢谢。

在清单中更改配置不是保存片段实例的推荐方法

相反,您应该将片段的实例保存在容器活动的onSaveInstanceState()重写方法中。 下面是一个小片段,可以帮助您:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState,"fragmentInstanceSaved",getSupportFragmentManager().findFragmentById(R.id.fragment_container));
}
现在,在容器活动的onCreate方法中,检查bundle是否为null:

    if(savedInstanceState!=null){
            Fragment fragment = getSupportFragmentManager().getFragment(savedInstanceState,"fragmentInstanceSaved");
            //recreate your preserved fragment here
        }else{
            //goto ur default activity or fragment....
}

在清单中进行配置更改不是保存片段实例的推荐方法

相反,您应该将片段的实例保存在容器活动的onSaveInstanceState()重写方法中。 下面是一个小片段,可以帮助您:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState,"fragmentInstanceSaved",getSupportFragmentManager().findFragmentById(R.id.fragment_container));
}
现在,在容器活动的onCreate方法中,检查bundle是否为null:

    if(savedInstanceState!=null){
            Fragment fragment = getSupportFragmentManager().getFragment(savedInstanceState,"fragmentInstanceSaved");
            //recreate your preserved fragment here
        }else{
            //goto ur default activity or fragment....
}

使用android:configChanges=“orientation | screenSize”属性设置Menifest文件中的活动谢谢。做chadil03说要做的事就像你离开的时候把你家的门敞开着,回来的时候直接穿过门。如果你想让内存泄漏窃贼进入你的房子,而你的记忆已经消失,你所有的记忆都可以自由使用这种方法。否则,请参见Kaveesh Kanwal给出的以下答案。将
android:configChanges=“orientation | screenSize”
属性用于Menifest中的活动