`

关于转屏,与activity状态的保存[转]

阅读更多
比较onSaveInstanceState() 与 onRetainNonConfigurationInstance()在不同需求中的用法

针对Android平台,不论出于哪种目的,都或多或少需要在多个Activities中的跳转操作,其中包括为了获得某些系统资源和必要信息,而通过启动(startActivity()&startActivityForResult() )Child Activity来提供一个选择器或者作为用户输入信息的介质。这期间父级Activity将暂时性失去焦点,从而在这之前先通过 onSaveInstanceState() 方法临时存储一些必要的信息,当父级的Activity重新成为当前焦点后,系统将触发 onRestoreInstanceState() 恢复失去焦点前的原有数据!onRetainNonConfigurationInstance()也具有相同的目的来处理类似的请求,其主要是由于旋转设备而更改显示模式,进而触发这个方法的调用。

那么在遇到某些特定需求时,特别是针对设备旋转后所导致的显示模式发生变化后,应该依据什么条件来判断应用哪种方式才能更好的满足需要呢?做出选择之前有必要分别了解两种方法的各自特点。

onSaveInstanceState()

在当前的Activity中通过新的Intent启动其它Activities之后,它将通过这个方法自动保存自身的数据,当再次出返回时可以通过 onRestoreInstanceState()复原数据。另外一种情况也将调用这个方法,当旋转设备后屏幕显示模式发生改变时。需要注意的一点是整个过程完全由系统控制,无法通过onSaveInstanceState()返回一个自定义的数据。

另外,onSaveInstanceState()在所有Activity destroying过程中被调用,它仅仅是为了在重新回到这个特定的Activity之后,依据Activity state重新创建一个与之前状态完全相同的Activity。例如:当我们启动某些Connection时,State并不能依然保存这个连接状态。所以当调用onSaveInstanceState后,所有当前的connection将一同销毁。当第二次通过 onRestoreInstanceState()找回之前的连接设置并重新建立新的连接实体。

如果大家有更多的发现,或者有不用于以上的验证结果,非常感谢能参与这个话题的讨论。

onRetainNonConfigurationInstance()

当Device configuration发生改变时,将伴随Destroying被系统调用。通过这个方法可以像onSaveInstanceState()的方法一样保留变化前的Activity State,最大的不同在于这个方法可以返回一个包含有状态信息的Object,其中甚至可以包含Activity Instance本身。新创建的Activity可以继承大量来至于Parent Activity State信息。

用这个方法保存Activity State后,通过getLastNonConfigurationInstance()在新的Activity Instance中恢复原有状态。

这个方法最大的好处是:

* 当Activity曾经通过某个网络资源得到一些图片或者视频信息,那么当再次恢复后,无需重新通过原始资源地址获取,可以快速的加载整个Activity状态信息。

* 当Activity包含有许多线程时,在变化后依然可以持有原有线程,无需通过重新创建进程恢复原有状态。

* 当Activity包含某些Connection Instance时,同样可以在整个变化过程中保持连接状态。

下边是需要特别注意的几点:

* onRetainNonConfigurationInstance()在onSaveInstanceState()之后被调用。
* 调用顺序同样介于onStop() 和 onDestroy()之间。

接下来将通过一个例子来简单了解onRetainNonConfigurationInstance()和getLastNonConfigurationInstance()的用法。

这个例子将首先启动一个包含两个按钮的Activity。其中一个按钮用于调用本地通讯录,并将所选择的某一项作为返回值传给当前 Activity。另外一个按钮的作用是查看当前所选择的通讯信息。正常的流程是当第一次启动程序后,第二个查看信息按钮是不可用状态。当通过Pick按钮确定选择并返回某一通讯录内容时,查看信息按钮的状态切换为可操作状态。然后当改变设备的Configuration时,可以注意到即便是 Activity通过onCreate()重新构建,但是之前所保证的UI属性依然保持最后一次操作的状态。

简单建立一个包含两个按钮的UI:
?View Code XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<Button android:id="@+id/pick"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="Pick"
    android:enabled="true"
/>
<Button android:id="@+id/view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="View"
    android:enabled="false"
/>
</LinearLayout>;

程序入口主程序代码如下所示(例子中包含了如何调用系统通讯录的方法):

package com.androidres.karka;

   import android.app.Activity;
   import android.content.Intent;
   import android.net.Uri;
   import android.os.Bundle;
   import android.view.View;
   import android.widget.Button;
   import android.util.Log;
   import android.provider.Contacts.People;

public class KarKa extends Activity {
static final int PICK_REQUEST=1337;
Button viewButton=null;
Uri contact=null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button btn=(Button)findViewById(R.id.pick);

btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i=new Intent(Intent.ACTION_PICK,
People.CONTENT_URI);

startActivityForResult(i, PICK_REQUEST);
}
});

viewButton=(Button)findViewById(R.id.view);

viewButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, contact));
}
});

restoreMe();

viewButton.setEnabled(contact!=null);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==PICK_REQUEST) {
if (resultCode==RESULT_OK) {
contact=data.getData();
viewButton.setEnabled(true);
}
}
}

@Override
public Object onRetainNonConfigurationInstance() {
return(contact);
}

private void restoreMe() {
contact=null;

if (getLastNonConfigurationInstance()!=null) {
contact=(Uri)getLastNonConfigurationInstance();
}
}
}
分享到:
评论

相关推荐

    测试Activity状态保存和恢复

    这就涉及到Activity状态的保存与恢复,确保用户在离开应用后返回时能够看到他们之前的操作状态。本篇将详细讨论如何在Android中测试和管理Activity的状态。 首先,了解Activity的生命周期是至关重要的。当Activity...

    设备旋转与Activity生命周期

    4. **使用Fragment**:Fragment可以在Activity之间独立管理其生命周期,当Activity重建时,已存在的Fragment不会被销毁,可以用来保存状态。 在GeoQuiz这样的应用中,设备旋转可能会影响游戏的进度或者用户的选择。...

    屏幕翻转Activity的生命周期

    3. **状态管理**:在`onSaveInstanceState()`和`onRestoreInstanceState()`方法中妥善处理数据的保存与恢复。 4. **测试不同场景**:确保在各种屏幕方向下都能正常工作。 通过以上分析,我们可以看到屏幕方向变化对...

    037集-Activity纵横屏切换的数据保存与恢复

    本教程“037集-Activity纵横屏切换的数据保存与恢复”深入探讨了如何在屏幕旋转时妥善处理数据保存与恢复的问题,以确保用户体验的连贯性。 首先,我们来了解Activity的生命周期。在Android中,Activity有多个状态...

    横竖屏切换Activity生命周期

    1. **onSaveInstanceState()**: 在屏幕旋转之前,系统会调用此方法,让你有机会保存Activity的状态信息。参数`Bundle outState`可以用来存储关键数据,如用户输入的数据或游戏状态。这是防止数据丢失的重要环节。 2...

    Android的Activity周期测试

    二、Activity状态转换测试 测试Activity生命周期通常通过模拟不同的用户操作和系统行为来观察回调方法的执行情况。例如,启动新Activity、按下Home键、收到来电、设备旋转等场景。通过Logcat记录各个回调方法的执行...

    activity生命周期

    Activity是Android应用开发中的核心组件,它代表了用户与应用交互的界面,是用户能看到和操作的窗口。理解Activity的生命周期对于开发高效、稳定的Android应用至关重要。Activity的生命周期包括了一系列的状态变化,...

    Activity生命周期完美呈现

    Activity是Android应用开发中的核心组件,它代表了用户与应用交互的界面。了解并掌握Activity的生命周期对于Android开发者至关重要,因为它决定了应用的行为和性能。在本文中,我们将深入探讨Activity的生命周期,...

    转屏的处理

    总结来说,"转屏的处理"涉及到移动开发中的用户界面适配、状态管理、生命周期回调以及性能优化等多个方面。开发者需要根据平台特性来编写合适的代码,以确保应用在屏幕旋转时能够正常工作并保持良好的用户体验。

    android Activity与Fragment

    然而,如果Activity有保存的实例状态,当用户返回时,系统会尝试恢复这些状态。 Fragment是Android 3.0(API级别11)引入的一个组件,用于在多个Activity之间共享UI元素。Fragment有自己的生命周期,但它的生命周期...

    Activity運作流程

    ### Activity運作流程 在Android应用开发中,`...理解这些状态及其转换对于确保`Activity`正确地管理其状态、保存和恢复数据至关重要。此外,合理地使用这些生命周期回调方法可以帮助开发者编写出更加健壮的应用程序。

    android activity 生命周期

    3. **运行状态**:`onResume()`方法调用后,Activity进入可交互状态,用户可以直接与之交互。此时,Activity处于前台,获取到焦点。 4. **暂停状态**:当另一个Activity覆盖当前Activity,或弹出一个透明/半透明...

    android activity示例

    6. 停止状态:当Activity完全不可见并且不再与用户交互时,它进入停止状态。此时,`onSaveInstanceState(Bundle outState)`可能会被调用,用来保存Activity的状态,以防被系统销毁。 7. 销毁状态:当Activity不再...

    深入理解Activity生命周期

    在这些状态转换中,Activity的状态保存和恢复也非常重要。`onSaveInstanceState(Bundle outState)`方法会在Activity即将被销毁或暂停时调用,用于保存临时或非持久性数据,如UI的状态。如果Activity被重新创建(例如...

    Activity生命周期demo

    在Activity状态转换过程中,系统会依次调用相应的生命周期方法,开发者可以在这些方法中进行必要的操作,如保存数据、释放资源等。例如,在`onPause()`和`onStop()`中可以保存Activity的状态信息,在`onResume()`中...

    QT安卓屏幕动态旋转

    8. **生命周期管理**:屏幕旋转会导致Activity的重建,因此需要处理好Activity的生命周期,确保在屏幕旋转后应用状态的正确恢复。 通过以上知识点的应用,你可以创建一个能够动态旋转屏幕的QT安卓应用。在实际项目...

    android 手机强制横竖屏

    Android系统默认支持屏幕自动旋转,当设备方向改变时,系统会重新创建Activity(onSaveInstanceState()保存状态,onDestroy()销毁,onCreate()重建,onRestoreInstanceState()恢复状态)。如果不想在横竖屏切换时...

    Fragment 与 Activity之间传递数据

    这种方法适用于双向通信,特别是当Fragment需要更新Activity的状态或者需要Activity执行某些操作时。 总之,Fragment与Activity之间的数据传递是Android开发中的重要技能。通过setArguments方法,我们可以方便地在...

    Android基础-2(Activity)

    为了在Activity状态改变时保存用户数据,Android提供了onSaveInstanceState(Bundle outState)和onRestoreInstanceState(Bundle savedInstanceState)方法。在系统准备销毁Activity时,会调用onSaveInstanceState(),...

Global site tag (gtag.js) - Google Analytics