前一讲我们介绍了Activity的生命周期,使用过Android智能手机的人都应该知道,有些应用当我们横竖切换手机时,显示界面也会调整到相应的状态下。那么当手机屏幕横竖切换时,activity的生命周期又是如何的呢?这讲我们将来解决这个问题。

本节我们通过一个发送短信的小程序来讲解这个问题,同时讲解一下Android发送短信功能的实现。

1、新建一个Android项目:SMS 2、编辑字符串strings.xml文件内容为:

<?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="hello"> Hello World, SmsActivity! </string>
     <string name="app_name"> Sms </string>
     <string name="tv_phone"> 手机号码 </string>
     <string name="tv_content"> 短信内容 </string>
     <string name="tip_phone"> 请输入手机号码 </string>
     <string name="tip_content"> 请输入短信内容 </string>
     <string name="btn_send"> 发送 </string>
     <string name="btn_cancel"> 取消 </string>
 </resources>

3、编辑layout布局文件main.xml文件内容为:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
	  <!-- 手机号码标签 -->
     <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tv_phone" />
     <!-- 手机号码编辑框 -->
     <EditText
        android:id="@+id/et_phone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="@string/tip_phone"
        android:phoneNumber="true"/>
     <!-- 信息内容标签 -->
     <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tv_content" />
      <!-- 信息内容编辑框 -->
     <EditText
        android:id="@+id/et_content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="@string/tip_content"
        android:minLines="3"/>
     <LinearLayout
         android:layout_width="fill_parent"
    	 android:layout_height="fill_parent"
    	 android:orientation="horizontal">
    	  <!-- 发送按钮 -->
         <Button
            android:id="@+id/btn_Send"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/btn_send"/>
         <!-- 取消按钮 -->
         <Button
            android:id="@+id/btn_Cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/btn_cancel"/>
     </LinearLayout>

 </LinearLayout>

4、SmsActivity.java代码内容为:

package com.liuzhichao.sms;

import java.util.List;

import android.app.Activity;
import android.content.res.Configuration;
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);
    }

    @Override
	protected void onStart() {
		super.onStart();
		Log.i(TAG, "onStart()");
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		 Log.i(TAG, "onRestart()");
	}

	@Override
	protected void onPause() {
		super.onPause();
		 Log.i(TAG, "onPause()");
	}

	@Override
	protected void onStop() {
		super.onStop();
		 Log.i(TAG, "onStop()");
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		 Log.i(TAG, "onDestroy()");
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		 Log.i(TAG, "onConfigurationChanged()");
	}

	@Override
	protected void onResume() {
		super.onResume();
		 Log.i(TAG, "onResume()");
	}

	//发送按钮事件处理
    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();
			}
		};
}

5、编辑AndroidManifest.xml内容:

<?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liuzhichao.sms"
    android:versionCode="1"
    android:versionName="1.0" >

     <uses-sdk android:minSdkVersion="8" />
     <!-- 声明发送短信的权限  -->
     <uses-permission android:name="android.permission.SEND_SMS"/>
     <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
         <activity
            android:name=".SmsActivity"
            android:label="@string/app_name" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />

                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
     </application>

 </manifest>

6、运行项目,观察Logcat中的打印:

7、按Ctrl+F12切换成横屏时:

 

8、再按Ctrl+F12切换成竖屏时,发现打印了两次相同的log:

 

9、我们修改一下AndroidManifest.xml,把该Activity添加 android:configChanges="orientation"

	<activity
      android:name=".SmsActivity"
      android:label="@string/app_name"
      android:configChanges="orientation">
        <intent-filter>
          <action android:name="android.intent.action.MAIN">
          <category android:name="android.intent.category.LAUNCHER">
        </intent-filter>
   </activity>

重新运行项目,打印log如下:

10、同样我们再按Ctrl+F12切换成横屏时:

11、再按Ctrl+F12切换成竖屏发现不会再打印相同信息,但多打印了一行onConfigChanged:

12、我们再修改一下AndroidManifest.xml,把该Activity添加 android:configChanges="orientation|keyboardHidden"

<activity
            android:name=".SmsActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden">
             <intent-filter>
                <action android:name="android.intent.action.MAIN">
                 <category android:name="android.intent.category.LAUNCHER">
             </intent-filter>
 </activity>

13、同7一样,按Ctrl+F12切换成横屏

14、再按Ctrl+F12切换成竖屏

** 总结 ** :

  • 1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
  • 2、设置Activity的android:configChanges=“orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
  • 3、设置Activity的android:configChanges=“orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

附:在开发游戏的时候,有些游戏是只能横屏玩的,所以手机竖立放置的时候,要保持游戏画面依然横屏。要做到这个要求其实很简单,在AndroidManifest.xml里面配置一 下就可以了。加入这一行android:screenOrientation="landscape"