通过实例讲解屏幕切换同时保持Activity状态

刚开始学习android的时候,写了一个短信的小程序,但是那个程序有个bug,当我们编辑了短信将要发送 的时候,如果你不小心把手机屏幕切换了一下,然后你会发现你编辑的短信已经被清空了,这时又要重新编辑。试想一下,当我们好不容易编辑了一条短信,然后 突然一个电话打过来了,然后你接完电话返回到短信的界面时,你却发现你刚才编辑的短信成了空白,你心底一定会骂,是哪个二货设计的这个功能,太他妈不人性 化了。 这篇文章就是要解决这个问题。

当然,保存Activity状态的方法有多种,我们这讲来介绍一下通过重写Activity的onSaveInstanceState事件处理函数来保存Activity的状态。

我们修改一下上节中发短信的小例子,在SmsActivity.java中添加如下代码:

package com.liuzhichao.sms;
 
import java.util.List;
 
import android.app.Activity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
 
public class SmsActivity extends Activity {
    private static final String TAG="SmsActivity";
    //声明组件
    private EditText et_phone;
    private EditText et_content;
    private Button btn_Send;
    private Button btn_Cancel;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.i(TAG, "----onCreate()----");
        //根据ID获取组件
        et_phone = (EditText)findViewById(R.id.et_phone);
        et_content = (EditText)findViewById(R.id.et_content);
        btn_Send = (Button)findViewById(R.id.btn_Send);
        btn_Cancel = (Button)findViewById(R.id.btn_Cancel);
         
        //注册按钮单击事件
        btn_Send.setOnClickListener(btn_Send_ClickListener);
        btn_Cancel.setOnClickListener(btn_Cancel_ClickListener);
         
        //应用程序被迫重启,那么,保存的Bundle会传入到onRestoreInstanceState和onCreate方法中
        //如果savedInstanceState不为空
        if (null != savedInstanceState ){
            //判断savedInstanceState中是否保存了用户输入的手机号码
            if (savedInstanceState.containsKey("phoneString")) {
                et_phone.setText(savedInstanceState.getString("phoneString"));
            }
            //判断savedInstanceState中是否保存了用户输入的短信内容
            if (savedInstanceState.containsKey("contentString")) {
                et_content.setText(savedInstanceState.getString("contentString"));
            }
        }
    }
     
    /**
     * 覆盖onSaveInstanceState保存用户输入的手机号码和短信内容
     * 使用它的Bundle参数来保存实例的值
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
         
        String phoneString = et_phone.getText().toString();
        String contentString=et_content.getText().toString();
         
        //如果手机号码和短信内容不为空
        if (!"".endsWith(phoneString)) {
            outState.putString("phoneString", phoneString);
        }
        if (!"".endsWith(contentString)) {
            outState.putString("contentString", contentString);
        }
         
        super.onSaveInstanceState(outState);
    }
  
    
    //发送按钮事件处理
    private OnClickListener btn_Send_ClickListener = new OnClickListener() {
        public void onClick(View v) {
            //获取电话号码和知道内容
            String phoneString = et_phone.getText().toString();
            String contentString=et_content.getText().toString();
             
            //判断号码是否为空
            if("".equals(phoneString)){
                //提示电话号码不能为空
                Toast.makeText(SmsActivity.this, R.string.tip_phone, Toast.LENGTH_LONG).show();
                et_phone.requestFocus(); //让号码框获取焦点
                return;
            }
            //判断短信内容是否为空
            if ("".equals(contentString)) {
                //提示短信内容不为能空
                Toast.makeText(SmsActivity.this, R.string.tip_content, Toast.LENGTH_LONG).show();
                et_content.requestFocus();//让短信内容输入框获取焦点
                return;
            }
             
             SmsManager sms = SmsManager.getDefault();
             // 如果短信没有超过限制长度,则返回一个长度的List。
              List<String> texts = sms.divideMessage(contentString);
              for (String text:texts) {
                  sms.sendTextMessage(phoneString, null, text, null, null);
                  //发送成功后清空号码和短信内容
                  et_content.setText("");
                  et_phone.setText("");
                  Log.i(TAG, "短信发送成功!");
            }
        }
    };
     
    //取消按钮事件处理
     private OnClickListener btn_Cancel_ClickListener = new OnClickListener() {
            public void onClick(View v) {
                SmsActivity.this.finish();
            }
        };
         
     
         
         
}

onSaveInstanceState()这个处理函数会在Activity的Active生命周期结束时触发,但仅在它不是显式地结束(即异常结束)。因此,它一般用于确保在单个用户会话中的Active生命周期间Activity状态的一致性。

注: 有一点很重要的是,记住onSaveInstanceState仅在Activity变成非Active状态时调用,但不在调用finish来关闭它或用 户按下Back按钮时调用。由于onSaveInstanceState()并不是每次销毁时都会调用,所以不要在其中保存那些需要永久化的数据,执行保 存那些数据的最好地方是:onPause()中。