Android中横竖屏相关事宜

本文详细探讨了Android应用在不同屏幕方向切换时Activity的生命周期变化,并提供了避免生命周期重启的有效策略,包括配置文件设置和数据保存方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

</pre> 最近在做公司项目时,发现横竖屏切换和我原来的认知不太一样,原来我是知道同一个Activity横竖屏切换时,会导致生命周期重启。那么今天就趁此机会将android中横竖屏相关的知识总结一下。<p></p><p></p><p><strong><span style="white-space:pre"></span>首先,我们看同一个activity横竖屏,会执行那么生命周期中的方法:</strong></p><p><span style="white-space:pre"></span>代码如下:</p><p><span style="white-space:pre"></span></p><pre name="code" class="java">package com.example.demo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {
	
	private static final String tag = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.d(tag, "onCreate");
	}
	
	@Override
	protected void onStart() {
		Log.d(tag, "onStart");
		super.onStart();
	}
	
	@Override
	protected void onResume() {
		Log.d(tag, "onResume");
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		Log.d(tag, "onPause");
		super.onPause();
	}
	
	@Override
	protected void onStop() {
		Log.d(tag, "onStop");
		super.onStop();
	}
	@Override
	protected void onDestroy() {
		Log.d(tag, "onDestroy");
		super.onDestroy();
	}
	
}


1. 先看竖屏时,启动以后会执行那些生命周期:

01-23 22:34:30.659: D/MainActivity(12738): onCreate
01-23 22:34:30.659: D/MainActivity(12738): onStart
01-23 22:34:30.659: D/MainActivity(12738): onResume

2. 我们将手机横屏以后,看看会执行那些周期回调方法:

01-23 22:39:43.809: D/MainActivity(12738): onPause
01-23 22:39:43.809: D/MainActivity(12738): onStop
01-23 22:39:43.809: D/MainActivity(12738): onDestroy
01-23 22:39:43.869: D/MainActivity(12738): onCreate
01-23 22:39:43.869: D/MainActivity(12738): onStart
01-23 22:39:43.869: D/MainActivity(12738): onResume
可以明显看出,横屏以后,又将执行oncreate/onstart/onresume这些方法,也就是生命周期重启了。如果不太了解这个知识点的话,再写代码时很容易掉坑里边。接下来我们就要想想如何防止生命周期重启。

 <activity 
            android:name="com.example.demo.MainActivity"
             android:configChanges="orientation|keyboard|screenSize"
            >
            
            <intent-filter >
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            
        </activity>

需要配置android:configChanges="orientation|keyboard|screenSize"的信息。配置完成以后,横竖屏以后就不会再重启了。这是其中的一个方法。另外的方法,就算重启了,我们可以保存一些数据。重启以后又重新拿到这些数据,就算重启了,也不会有什么影响。

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// 当activity回收、横竖屏切换时,用于保存数据。
		outState.putString("name", "boss");
		super.onSaveInstanceState(outState);
	}

在activity中重写该方法,用于保存数据。然后在oncreate中获取数据。

protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.d(tag, "onCreate");
		
		if (savedInstanceState != null){
			String name = savedInstanceState.getString("name");
			if (name == null){
				Log.d(tag, "null");
			}else{
				Log.d(tag, name);
			}
		}
		
	}
以上就总结了同一个activity时,如何保存数据的问题。


接下来,我们看看两个不同的activity时,生命周期也会重启的。我们来看看测试结果。

另一个activity配置成横屏。结果发现竖屏的activity启动横屏的activity以后,自己的生命周期又重启。如何避免重启,或者如何保存数据,上面已经介绍。记录了这么多也算留个记号吧。

public void click(View view){
		Intent intent = new Intent(this, Main1Activity.class);
		startActivity(intent);
	}
01-23 23:17:34.239: D/MainActivity(26184): onPause
01-23 23:17:34.239: D/MainActivity(26184): onStop
01-23 23:17:34.239: D/MainActivity(26184): onDestroy
01-23 23:17:34.299: D/MainActivity(26184): onCreate
01-23 23:17:34.299: D/MainActivity(26184): onStart
01-23 23:17:34.299: D/MainActivity(26184): onResume






<think>好的,用户需要封装一个改变Android设备横竖屏的方法。首先,我需要回忆一下Appium中控制设备方向的方法。Appium的WebDriver提供了`set_orientation`方法,可以设置设备的方向为'PORTRAIT'(竖屏)或'LANDSCAPE'(横屏)。不过,可能需要考虑不同自动化驱动(如UiAutomator2)的兼容性。 首先,用户可能需要一个方法,接收目标方向作为参数,比如'portrait'或'landscape',然后通过Appium驱动来设置。需要处理可能的异常,比如方向参数错误,或者驱动连接问题。 然后,需要考虑验证方向是否设置成功。可以通过`driver.orientation`获取当前方向,设置后检查是否与目标一致。如果不一致,可能需要重试或抛出异常。 另外,用户可能需要处理一些边界情况,比如设备本身不支持旋转,或者有应用锁定了屏幕方向。这时候需要给出提示或处理异常。 还需要注意,Appium的`set_orientation`方法是直接作用于设备的,所以不需要通过ADB命令,而是利用驱动提供的接口。这样更简洁,兼容性更好。 接下来,封装方法的步骤可能包括: 1. 定义方法,接收driver和目标方向作为参数。 2. 验证目标方向是否合法(只能是'PORTRAIT'或'LANDSCAPE')。 3. 使用`driver.set_orientation`设置方向。 4. 验证设置是否成功,通过获取当前方向检查。 5. 处理可能的异常,比如参数错误、设置失败等。 另外,可能需要考虑显式等待,确保方向切换完成,因为有些设备切换方向需要时间,立即检查可能不准确。 还需要提供使用示例,让用户知道如何调用这个方法。同时,注意事项部分需要提到设备兼容性、应用限制等。 现在,把这些思路整理成一个结构清晰的方法,包括代码实现、说明、示例和注意事项。 </think>以下是使用 Appium 封装的 **Android 设备横竖屏切换方法**,支持设置目标方向(竖屏/横屏)并验证操作结果,兼容 UiAutomator2 驱动: ### 方法实现(Python + Appium) ```python from appium.webdriver.common.mobileby import MobileBy from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium.webdriver.webdriver import WebDriver def set_device_orientation(driver: WebDriver, target_orientation: str) -> bool: """ 设置 Android 设备的横竖屏方向 :param driver: Appium WebDriver 对象(已连接设备) :param target_orientation: 目标方向('portrait' 竖屏 / 'landscape' 横屏,不区分大小写) :return: 操作是否成功(True=切换完成/已处于目标状态,False=失败) """ # 步骤1:校验目标方向参数 valid_orientations = {'portrait', 'landscape'} target_orientation = target_orientation.lower() if target_orientation not in valid_orientations: print(f"无效方向参数:{target_orientation},仅支持 'portrait' 或 'landscape'") return False try: # 步骤2:获取当前设备方向 current_orientation = driver.orientation.lower() if current_orientation == target_orientation: print(f"设备已处于 {target_orientation} 方向,无需操作") return True # 步骤3:设置目标方向(Appium 内置方法) driver.set_orientation(target_orientation.upper()) # 转换为大写(如 'PORTRAIT') # 步骤4:验证方向切换是否成功(显式等待 10s 确保完成) WebDriverWait(driver, 10).until( lambda d: d.orientation.lower() == target_orientation, message=f"方向切换超时,当前方向仍为 {current_orientation}" ) print(f"设备方向成功切换为 {target_orientation}") return True except Exception as e: print(f"方向切换失败,异常信息:{str(e)}") return False ``` ### 方法说明 1. **参数校验**: 强制校验目标方向是否为 `portrait`(竖屏)或 `landscape`(横屏),避免因错误参数导致操作失败。 2. **当前状态检查**: 通过 `driver.orientation` 获取设备当前方向(返回值为 `'PORTRAIT'` 或 `'LANDSCAPE'`),若已处于目标状态则直接返回成功,避免重复操作。 3. **方向设置**: 使用 Appium 内置的 `set_orientation` 方法(参数需为大写),直接调用设备底层接口切换方向,无需通过 ADB 命令,兼容性更好。 4. **切换验证**: 通过 `WebDriverWait` 显式等待 10 秒,确保方向切换完成(部分设备/应用切换可能有延迟)。若超时未完成,抛出异常并返回失败。 ### 使用示例 ```python from appium import webdriver # 初始化 Appium driver(以 Android 设备为例) desired_caps = { "platformName": "Android", "deviceName": "your_device_name", "platformVersion": "13", # 根据实际设备版本调整 "automationName": "UiAutomator2", "appPackage": "com.android.settings", # 任意已安装应用均可(非必须) "noReset": True } driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps) # 切换为竖屏 set_device_orientation(driver, "portrait") # 输出:设备方向成功切换为 portrait # 切换为横屏 set_device_orientation(driver, "landscape") # 输出:设备方向成功切换为 landscape # 重复切换(已处于目标状态) set_device_orientation(driver, "landscape") # 输出:设备已处于 landscape 方向,无需操作 # 退出驱动 driver.quit() ``` ### 注意事项 1. **设备/系统限制**: - 部分设备(如折叠屏、平板)可能不支持某些方向切换(如强制竖屏),需提前确认设备物理特性。 - 部分应用(如游戏、视频类)可能通过 `android:screenOrientation` 锁定方向,此时 `set_orientation` 无法改变应用内方向(需应用本身支持)。 2. **驱动兼容性**: - 确保使用 Appium 1.18+ 或 Appium 2.0+ 版本(旧版本可能存在 `set_orientation` 兼容性问题)。 - UiAutomator2 驱动对方向切换的支持优于旧版 UIAutomator 驱动,建议使用 `automationName: "UiAutomator2"`。 3. **应用界面适配**: 切换方向后,应用界面可能需要重新布局(如控件位置变化),建议在切换后添加显式等待(如 `WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.ID, "target_id")))`)确保元素加载完成。 4. **物理按键干扰**: 若设备启用了“自动旋转”(通过 `adb shell settings get system accelerometer_rotation` 检查,1=开启),切换方向后可能被重力感应覆盖。可通过以下命令临时关闭自动旋转: ```bash adb shell settings put system accelerometer_rotation 0 # 关闭自动旋转 adb shell settings put system accelerometer_rotation 1 # 恢复自动旋转 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值