【问题标题】:How to use onSavedInstanceState example please请如何使用 onSavedInstanceState 示例
【发布时间】:2011-06-29 18:51:15
【问题描述】:

当谈到保存状态时,我很困惑。所以我知道onSaveInstanceState(Bundle) 在活动即将被销毁时被调用。但是您如何将您的信息存储在其中并将其恢复到onCreate(Bundle savedInstanceState) 中的原始状态?我不明白这个捆绑包将如何恢复信息。如果有人可以提供一个例子,那将会很有帮助。 开发指南没有很好地解释这一点。

public class Conversation extends Activity {
    private ProgressDialog progDialog;
    int typeBar;
    TextView text1;
    EditText edit;
    Button respond;
    private String name;
    private String textAtView;
    private String savedName;

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.dorothydialog);
        text1 = (TextView)findViewById(R.id.dialog);
        edit = (EditText)findViewById(R.id.repsond);
        respond = (Button)findViewById(R.id.button01);

        if(savedInstanceState != null){
            savedInstanceState.get(savedName);
            text1.setText(savedName);
        }
        else{
            text1.setText("Hello! What is your name?");
            respond.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    name = edit.getText().toString();
                    text1.setText("Nice to meet you "+ name);
                }   
            });
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putString(savedName, name);
    }
}

【问题讨论】:

  • text1.setText(savedInstanceState.getString(savedName));
  • @Spidy onBackpressed 怎么样?我将如何使用捆绑包对此做出反应?
  • 你不会的。当用户按下后退按钮时。活动被杀死。使用数据库进行永久数据存储。使用 Bundle 将重新启动的应用程序返回到之前的状态。

标签: android savestate


【解决方案1】:

Bundle 是您要保存的所有信息的容器。您使用 put* 函数将数据插入其中。这是一个简短的列表(还有更多),您可以使用这些函数将数据存储在 Bundle 中。

putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)

在你的onCreate 函数中,这个Bundle 被交还给程序。检查应用程序是否正在重新加载或首次启动的最佳方法是:

if (savedInstanceState != null) {
    // Then the application is being reloaded
}

要取回数据,请使用 get* 函数,就像 put* 函数一样。数据存储为名称-值对。这就像一个哈希图。您提供一个键和值,然后当您想要返回值时,您提供键并且函数获取值。这是一个简短的示例。

@Override
public void onSaveInstanceState(Bundle outState) {
   outState.putString("message", "This is my message to be reloaded");
   super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String message = savedInstanceState.getString("message");
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

您保存的消息将被烤到屏幕上。希望这会有所帮助。

【讨论】:

  • onSaveInstanceState() 在您的活动暂停之前被调用。因此,它可能被破坏后所需的任何信息都可以从保存的 Bundle 中检索
  • @Spidy 太棒了!你真的让我明白了关于捆绑的一切!所以我猜 outState 被传回了 savedInstanceState 包?对吗?
  • 是的。 outState Bundle 作为 savedInstanceState Bundle 传回
  • @tj walker - 另一个很好的资源是技术参考书。 Pro Android 3 是您可以在亚马逊上获得的廉价但广泛的资源
  • @Spidy 我在上面发布了我的活动代码供您查看。也许你可以让我知道我是否按照你的建议正确保存了我的状态。
【解决方案2】:

所有新的 Android 开发人员都应该知道的一个主要注意事项是,只要您为 Widgets(TextView、Buttons 等)分配了 ID,Android 就会自动保存它们中的任何信息。所以这意味着大部分 UI 状态都可以毫无问题地处理。只有当您需要存储其他数据时,这才会成为问题。

来自Android Docs

您需要做的唯一工作是 提供一个唯一的 ID(带有 android:id 属性)为每个小部件 你想保存它的状态。如果一个 小部件没有 ID,那么它 无法保存其状态

【讨论】:

  • 这是真的吗?因为我有一个带有按钮 textview 和编辑文本的活动。如果应用程序被破坏或杀死,一切都会恢复到原始状态。在我的应用程序中,每次用户单击按钮时,textView 文本都会发生变化。
  • 文档不准确吗?我从来没有让 View 保存自己的信息。在我看来,最好的办法是自己保存所有信息。
  • 如果您的目标是保存信息 onSaveInstanceState 不是这样做的地方。那是因为不能保证它会被调用(参见文档)。您应该改为写入数据库、SharedPreferences 等。是的,此信息是准确的。测试您的 UI 是否以这种方式持续存在的最佳方法是在方向更改时旋转您的显示器重新运行您的 onCreate 并使用捆绑包恢复状态。
  • @Nissan Fan 你能举个像上面spidy那样的例子吗?与sharedprefs 和所有?谢谢
  • 坦率地说,最好的例子来自文档。 developer.android.com/guide/topics/data/data-storage.html#pref
【解决方案3】:

一个很好的信息:您不需要在 onCreate() 方法中检查 Bundle 对象是否为空。使用系统在 onStart() 方法之后调用的 onRestoreInstanceState() 方法。系统只有在有保存状态需要恢复时才会调用onRestoreInstanceState(),所以不需要检查Bundle是否为空

【讨论】:

    【解决方案4】:

    店铺信息:

    static final String PLAYER_SCORE = "playerScore";
    static final String PLAYER_LEVEL = "playerLevel";
    
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save the user's current game state
        savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
        savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);
    
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
    }
    

    如果您不想在 onCreate-Method 中恢复信息:

    以下是示例:Recreating an Activity

    您可以选择实现 onRestoreInstanceState(),而不是在 onCreate() 期间恢复状态,系统在 onStart() 方法之后调用它。系统只有在有保存状态需要恢复时才会调用onRestoreInstanceState(),所以不需要检查Bundle是否为null

    public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);
    
    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
    mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
    }
    

    【讨论】:

      【解决方案5】:

      基本上 onSaveInstanceState(Bundle outBundle) 会给你一个包。 当您查看 Bundle 类时,您会发现可以在其中放入许多不同的东西。在下一次调用 onCreate() 时,您只需将该 Bundle 作为参数返回。 然后您可以再次读取您的值并恢复您的活动。

      假设您有一个带有 EditText 的活动。用户在其中写了一些文本。 之后系统调用您的 onSaveInstanceState()。 您从 EditText 读取文本并通过 Bundle.putString("edit_text_value", theValue) 将其写入 Bundle。

      现在 onCreate 被调用。您检查提供的捆绑包是否不为空。如果是这样的话, 您可以通过 Bundle.getString("edit_text_value") 恢复您的值并将其放回您的 EditText。

      【讨论】:

        【解决方案6】:

        这是为了提供更多信息。

        想象一下这个场景

        1. ActivityA 启动 ActivityB。
        2. ActivityB 启动一个新的 ActivityAPrime by

          Intent intent = new Intent(getApplicationContext(), ActivityA.class);
          startActivity(intent);
          
        3. ActivityAPrime 与 ActivityA 没有关系。
          在这种情况下,ActivityAPrime.onCreate() 中的 Bundle 将为空。

        如果 ActivityA 和 ActivityAPrime 应该是同一个活动而不是不同的活动, ActivityB 应该调用 finish() 而不是使用 startActivity()。

        【讨论】:

        • 只是为了澄清,在您的示例中,ActivityA == ActivityA 实例 1 和 ActivityAPrime == ActivityA 实例 2?此外,当您说“ActivityB 应该调用 finish() 而不是使用 startActivity()”时。你的意思是:(1) AcitivityB 应该调用 finish() 然后使用 startActivity() (2) 或者 ActivityB 应该调用 finish() 而不是使用 startActivity()?如果您的意思是选项 2,您将如何建议某人重新启动相同的 activityA instance1,以便您可以在被销毁/完成之前加载活动包含的数据?谢谢
        • ActivityA 和 ActivityAPrime 属于同一类,但实例不同。在这个场景中,ActivityA还没有完成它的业务,在它的中间,它创建并启动了ActivityB,所以当ActivityB完成时,ActivityA应该继续它剩余的业务。在这种情况下调用 startActivity 并期望 ActivityA 和 ActiviyAPrime 是同一个实例是错误的。所以我们不应该重新启动ActivityA,只需完成ActivityB并让ActivityA恢复运行......
        【解决方案7】:

        如果没有从savedInstanceState 加载数据,请使用以下代码。
        问题是 url 调用没有完全完成,所以检查数据是否加载然后显示 instanceState 值。

        //suppose data is not Loaded to savedInstanceState at 1st swipe
        if (savedInstanceState == null && !mAlreadyLoaded){
            mAlreadyLoaded = true;
            GetStoryData();//Url Call
        } else {
            if (listArray != null) {  //Data Array From JsonArray(ListArray)
                System.out.println("LocalData  " + listArray);
                view.findViewById(R.id.progressBar).setVisibility(View.GONE);
            }else{
                GetStoryData();//Url Call
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-24
          相关资源
          最近更新 更多