您现在的位置是:首页 >其他 >使用onSaveInstaceState保存活动信息网站首页其他

使用onSaveInstaceState保存活动信息

高自期许 2024-06-17 10:32:20
简介使用onSaveInstaceState保存活动信息

工程地址:https://github.com/MADMAX110/Stopwatch

上次实现了一个Android秒表应用,在模拟器里运行这个应用,应用没有任何问题,但是在真实设备上运行这个应用时,旋转设备的方向,秒表会自动归零。下面分析一下是什么导致了这个问题。
1、用户启动应用,单击Start,开始运行。runTimer使用seconds和running变量开始递增文本视图中显示的秒数。
2、用户旋转设备之后,Android看到屏幕方向和大小发生变化,他会撤销这个活动,包括runTimer使用的所有变量。
3、然后重新创建StopwatchActivity。变量均会重置为默认值。

这是因为旋转屏幕会改变Android设备配置,设备配置包括用户指定的选项(如本地化环境),以及与真实设备相关的选项(如方向和屏幕大小),其中任何选项的改变都会导致撤销活动,然后重新创建活动。

要处理配置改变的问题,最好的办法是保存活动的当前状态,然后在活动的onCreate方法中恢复这个状态。要保存活动的当前状态,需要实现onSaveInstanceState方法,这个方法会在活动被撤消之前调用。

   @Override
    protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
        savedInstanceState.putInt("seconds", seconds);
        savedInstanceState.putBoolean("running", running);
    }

onSavedInstanceState()方法有一个参数Bundle,利用Bundle可以把不同类型的数据收集到一个对象中。
onCreate()方法得到作为参数传入的Bundle,onCreate方法会在活动创建时重新得到这些值。
Bundle可以使用bundle.put*(“name”, value)方法添加值。

在onCreate中添加一下代码可以获取之前存过的信息

if (savedInstanceState != null) {
     seconds = savedInstanceState.getInt("seconds");
     running = savedInstanceState.getBoolean("running");
 }

以下是改好后的完整的StopwatchActivity代码。

package com.hfad.stopwatch;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Locale;
import android.os.Handler;

import androidx.annotation.NonNull;


public class StopwatchActivity extends Activity {

    private int seconds = 0;//记录已经过去的秒数
    private boolean running;//秒表是否正常运行
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stopwatch);
        if (savedInstanceState != null) {
            seconds = savedInstanceState.getInt("seconds");
            running = savedInstanceState.getBoolean("running");
        }

        runTimer();//使用单独的方法更新秒表。创建活动会调用这个方法
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
        savedInstanceState.putInt("seconds", seconds);
        savedInstanceState.putBoolean("running", running);
    }

    //启动秒表
    public void onClickStart(View view) {
        running = true;
    }

    //停止秒表
    public void onClickStop(View view) {
        running = false;
    }

    //单击reset按钮时会调用这个方法
    public void onClickReset(View view) {
        running = false;
        seconds = 0;
    }

    private void runTimer() {
        //得到文本视图
        final TextView timeView = (TextView) findViewById(R.id.time_view);
        //创建一个新地Handler
        final Handler handler = new Handler();
        //调用post()方法,传入一个新的Runnable。post()方法会立即运行代码
        handler.post(new Runnable() {
            public void run() {

                int hours = seconds / 3600;
                int minutes = (seconds%3600)/60;
                int secs = seconds % 60;
                //设置显示格式
                String time = String.format(Locale.getDefault(), "%d:%02d%02d", hours, minutes, secs);
                //设置文本视图
                timeView.setText(time);
                if (running) {
                    ++seconds;
                }

                //在1000ms后再次提交并运行Runnable中的代码,会反复调用
                handler.postDelayed(this, 1000);
            }
        });
    }
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。