如何使用 onSaveInstanceState android 方向更改

Posted

技术标签:

【中文标题】如何使用 onSaveInstanceState android 方向更改【英文标题】:How to work with onSaveInstanceState android orientation change 【发布时间】:2018-04-09 17:42:32 【问题描述】:

我正在使用 android 上的 web 服务。我正在关注其中一个 lynda.com 上的教程。我确实经历了tuorial。我得到数据 来自 webservice 并将其显示在“ListView”中。我有 MainActivity 类 以及扩展 IntentServcie 的 MyService 类,以及实现 Parcelable 的 POJO 类名 Course。它包含我得到的网络服务响应的一部分 点击。

public class MainActivity extends AppCompatActivity 
//member variables I have
    ListView listview;
    List<String> courseList = new ArrayList<>();
    ArrayAdapter<String> adapter;
    Course[] courses;
......
    public void runClickHandler(View view) 
        Intent intent = new Intent(this, MyService.class);
        //the url where I extract the JSON data
        intent.setData(Uri.parse(JSON_URL));
        startService(intent);

    

在 MyService 类中,从 web 服务下载响应并 我打开一个连接

 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 conn.addRequestProperty("Authorization", TOKEN);

我使用 GSON 库转换 JSON ,打包数据并使用 LocalBroadcastManager 将其发送到 MainActivity。

protected void onHandleIntent(Intent intent) 
          ...........
          messageIntent.putExtra(MY_SERVICE_PAYLOAD, courseList);
        //we package the data we want to share to the rest of the applicaiton
        LocalBroadcastManager manager =   LocalBroadcastManager.getInstance(getApplicationContext());
        manager.sendBroadcast(messageIntent);
        

在我的 MainActivity 上,我使用 BroadcastReceiver 获取数据并将其显示在列表视图上。 BroadcastReceiver 的 OnReceive 方法内部。我有这个

public void onReceive(Context context, Intent intent) 
            courses = (Course[]) intent.getParcelableArrayExtra(MyService.MY_SERVICE_PAYLOAD);

            for (Course course : courses) 

                courseList.add(course.getCourseTitle());
            
            Collections.sort(courseList);

           adapter = new ArrayAdapter<String>(
                    MainActivity.this,
                    android.R.layout.simple_expandable_list_item_1,
                    courseList);

            listview.setAdapter(adapter);

        

当我改变屏幕方向时,问题就来了。我从 web 服务获得的数据被破坏了。我阅读了在 XML 文件上设置内容以调整屏幕大小更改的建议,这也被认为不是“好方法”。我认为使用的是覆盖此处或在线其他帖子所建议的 onSaveInstanceState 。我确实很难连接各个部分,并在方向更改期间保留我的数据。 我应该如何处理事情?我会很感激您阅读的任何好文章,或者您如何根据我上面的实现来解决问题。检查 if(savedInstanceState != null) 后如何处理显示 onCreate?我应该保存哪些成员变量数据?是否一切都更改为 null onDestroy()?这是我有的 onCreate() 方法

    protected void onCreate(Bundle savedInstanceState) 

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

    LocalBroadcastManager.getInstance(getApplicationContext())
   .registerReceiver(mBroadcastReceiver,new IntentFilter(MyService.MY_SERVICE_MESSAGE));

            listview = (ListView) findViewById(R.id.list);

        

【问题讨论】:

【参考方案1】:

1.

onSaveInstanceState(Bundle out) 
    out.putParcelableArrayList("COURSES", courseList);

2.

onCreate(Bundle savedState) 
    // ...
    if (savedState != null) 
         courseList = savedState.getParcelableArrayList("COURSES");
    

附: * https://developer.android.com/reference/android/os/Bundle.html * https://developer.android.com/guide/components/activities/activity-lifecycle.html#saras

【讨论】:

如果我在 onSaveInstanceState 上添加您建议的内容,我会收到错误错误的第二个参数类型。找到:'java.util.List',需要:'java.util.ArrayList 好的,我更新了您的反馈以使用 out.putParcelableArray("COURSES", courses);和 onCreate() 我得到了课程 courses = (Course[])savedInstanceState.getParcelableArray("COURSES");我仍然有显示课程的主要问题。最初课程是使用 onClick 触发器显示的,现在我希望它们显示屏幕旋转【参考方案2】:

甚至在我发布问题之前,我已经查看了教程和 *** 响应。我花了很长时间才消化。 MaxV 为我指明了正确的方向。在 savedInstanceState 我添加了这个

//I have coures parcelable array object as a member variable
// Course[] courses;
 @Override
    public void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);
        outState.putParcelableArray("COURSES", courses);

    

OnCreate() 方法我得到了一系列课程,我创建了另一个帮助方法来显示课程列表

if (savedInstanceState != null) 

            courses = (Course[])savedInstanceState.getParcelableArray("COURSES");
            displayListOfCourses(courses);
        

我创建了 displayListOfCourses,我从之前的 BroadcastReciever 中提取了部分代码,并使其可重用。我最初的假设是通过列出课程列表以某种方式显示该列表。现在,我的理解是我必须自己创建视图对象、ListView 和 arrayAdapter 并重建视图。

public void displayListOfCourses(Course[] courses)
        for (Course course : courses) 

            courseList.add(course.getCourseTitle());
        
        Collections.sort(courseList);

        adapter = new ArrayAdapter<String>(
                MainActivity.this,
                android.R.layout.simple_expandable_list_item_1,
                courseList);

        listview.setAdapter(adapter);

    

【讨论】:

以上是关于如何使用 onSaveInstanceState android 方向更改的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 onSaveInstanceState android 方向更改

如何将数据从 onCreate() 传递到 onSaveInstanceState()?

如何在活动的 onSaveInstanceState() 之后杀死所有打开的片段

我如何知道是不是调用了 onSaveInstanceState() 以避免 IllegalStateException?

如果我使用 SharedPreferences,使用 onSaveInstanceState 是不是有用

onSaveInstanceState() 和 onRestoreInstanceState()