Android-运行时配置变更

运行时配置变更

有些配置可能会在运行时候发生变化(屏幕方向,键盘和语言),发生变化时,android会重启正在运行的activity(先后调用onPause,onStop,onDestory,onCreate,onStart,onResume),重启是为了加载新资原适应新配置.

为了更好地处理重启行为,activity必须通过常规的生命周期恢复其以前的状态,android会在activity被销毁之前调用onSaveInstanceState(),来保存应用状态的数据,然后你可在onCreate()或onRestoreInstanceState()期间恢复状态.

但是,假如遇到重启并恢复大量数据不仅成本高昂,而且可能导致用户体验不佳,这种情况下,你可以:

  • 配置变更时保留对象

    允许activity在配置变更时重启,但是要将状态对象传递给activity的新实例.

  • 自行处理配置变更

    阻止系统在某些配置变更时重启activity,但是在配置确实发生变化时接收回调,根据需求手动更新activity

在配置变更期间保留对象

如果重启activity需要恢复大量数据,重新建立网络连接或其它耗时操作,那么配置变更会给用户带来不好的体验,而且,仅仅依靠onSaveInstanceState()回调保存的Bundle,可能无法完全恢复,无法携带大型对象(bitmap),这种情况下,可以通过保留Fragment来减轻初始化activity的负担,此片段可能包含你对保留的有状态对象的引用.

要将有状态的对象保留在Fragment片段中,请执行下列操作:

  1. 扩展Fragment类并声明对有状态对象的引用.

  2. 在创建片段后调用setRetainInstance(boolean)

  3. 将片段添加到activity

  4. 重启activity后,使用FragmentManager检索片段.

示例:

public class RetainedFragment extends Fragment {

    // 要存放的数据对象
    private MyDataObject data;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 保留这个片段
        setRetainInstance(true);
    }

    public void setData(MyDataObject data) {
        this.data = data;
    }

    public MyDataObject getData() {
        return data;
    }
}

public class MyActivity extends Activity {

    private RetainedFragment dataFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 在activity重启时查找保存的片段
        FragmentManager fm = getFragmentManager();
        dataFragment = (DataFragment) fm.findFragmentByTag(“data”);

        // 第一次创建对象和保存的数据
        if (dataFragment == null) {
            // add the fragment
            dataFragment = new DataFragment();
            fm.beginTransaction().add(dataFragment, “data”).commit();
            // load the data from the web
            dataFragment.setData(loadMyData());
        }

        // 通过dataFragment.getData()可以访问数据
        ...
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 保存数据到片段
        dataFragment.setData(collectMyLoadedData());
    }
}

自行处理配置变更

如果应用在特定配置变更期间无需更新资源,或者因为性能限制要尽量避免重启,则可声明activity将自行处理变更.

清单文件的activity元素的android:configChanges属性,常用值有

  • fontScale 改变全局字体大小

  • orientation 屏幕的方向变化

  • keyboardHidden 键盘的可访问性变化

  • keyboard 键盘类型发生变化

  • locale 地区更改,用户选择一个新的语言

  • screenSize 屏幕的大小变化

你可以设置多值,比如

android:configChanges=”orientation|keyboardHidden”

现在,其中一个配置发生变化时,activity不会重启,而是收到对onConfigurationChanged()的调用,向此方法传递Configuration对象指定新设备配置,你可以通过读取Configuration的字段,确定新配置,然后通过更新界面中使用的资源进行适当的更改,调用这个方法时,activity的Resources对象会相应地进行更新,根据新配置返回资源,这样,你就能在不重启activity的情况下轻松重置UI的元素.

注意:从API13开始,设备方向变化时,屏幕尺寸也会发生变化,所以除了设置orientation之外还有设置screenSize的值.

示例(检查方向):

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // 检查屏幕的方向
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值