您的位置:首页 > 移动开发 > Android开发

Android关于处理运行时变化如横竖屏切换等问题

2016-06-23 23:57 417 查看
一些Android设备在运行时,它的configuration可能会变化(例如:横竖屏切换,键盘的显示或者隐藏,所用语言的变化),当这些类似的变化发生时,如果在不做任何代码处理的情况下,android会重启当前正在运行的Activity(先回调
onDestroy()
方法,再回调
onCreate()
方法)。也许你会问android为什么会这么做,其实这么做的本意也就是为了通过加载一些可供替代的资源,帮助APP适应新的configuration。

为了处理好重新启动的Activity的数据或者状态,你可以在Activity的生命周期回调方
onSaveInstanceState()
来保存当前的数据
,然后在方法
onCreate()
或者
onRestoreInstanceState()
中取出数据以及恢复状态,该方法适合数据量小,比较简单的情况。

然而,如果你像上一段中介绍的方法保存大量的数据和状态的话,可能会造成内存消耗比较大或者用户体验差的情况(个人体验较深的是:如果播放器的横竖屏切换,像上一段所说的保存播放位置和状态的话,会有明显的卡顿),这种情况下,一般你有两个选择:

a.在activity的configuration变化时,依然让你的Activity重启,但是给你的restart的新Activity对象传递一个可以保存状态的对象;(个人理解就是,这个对象在该Restart过程中一直是保留着的)

b.自己处理configuration变化,阻止系统重启Activity,并且监听configuration(这样可以手动地刷新Activity)。

对于a种处理思路,有一种利用Fragment保存数据的方案:

1.继承Fragment,并且声明数据对象;

2.在该Fragment的
http://wear.techbrood.com/reference/android/app/Activity.html#onCreate%28android.os.Bundle%29" target=_blank>onCreate()
方法中调用
setRetainInstance(boolean)


3.把该Fragment对象加入到Activity中;

4.当Activity重启时,用
FragmentManager
重新获取该Fragment对象

public class RetainedFragment extends Fragment {

// 你想保存的数据对象
private MyDataObject data;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使改fragment不会销毁
setRetainInstance(true);
}

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

public MyDataObject getData() {
return data;
}
}
特别需要注意的是:在fragment中的需要保存的数据对象,不应该与context有关,例如:Adapter,View之类的,否则可能造成内存泄露

下面给出activity的示例代码:

public class MyActivity extends Activity {

private RetainedFragment dataFragment;

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

// 在restart()的时候找到包含数据的fragment
FragmentManager fm = getFragmentManager();
dataFragment = (DataFragment) fm.findFragmentByTag(“data”);

// 第一次创建fragment
if (dataFragment == null) {
dataFragment = new DataFragment();
fm.beginTransaction().add(dataFragment, “data”).commit();
//从网络加载数据并保存到fragment中
dataFragment.setData(loadMyData());
}

// 可以通过dataFragment.getData()获取数据
...
}

@Override
public void onDestroy() {
super.onDestroy();
// 保存数据到fragment中
dataFragment.setData(collectMyLoadedData());
}
}
对于b中思路的处理方案:

如果你的App不需要再一些特定的configuration变化时刷新资源或者你的App设计本来就是要避免Activity重启,你可以按照以下步骤:

1.在manifest文件中,不需要重启的Activity中加入

android:configChanges="orientation|keyboardHidden"
该代码说明,在横竖屏切换或者软键盘显示隐藏的时候不会重启该Activity.

2.监听状态改变:

@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();
}
}


好了,个人第一次翻译,希望大家指正交流,哈哈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: