您的位置:首页 > 其它

处理运行时变更,activity被销毁后的重建,常见于屏幕旋转

2017-11-02 15:29 393 查看
在配置变更期间保留对象

如果重启 Activity 需要恢复大量数据、重新建立网络连接或执行其他密集操作,那么因配置变更而引起的完全重启可能会给用户留下应用运行缓慢的体验。 此外,依靠系统通过
onSaveInstanceState()
 回调为您保存的 
Bundle
,可能无法完全恢复
Activity 状态,因为它并非设计用于携带大型对象(例如位图),而且其中的数据必须先序列化,再进行反序列化,这可能会消耗大量内存并使得配置变更速度缓慢。 在这种情况下,如果 Activity 因配置变更而重启,则可通过保留 
Fragment
 来减轻重新初始化
Activity 的负担。此片段可能包含对您要保留的有状态对象的引用。

当 Android 系统因配置变更而关闭 Activity 时,不会销毁您已标记为要保留的 Activity 的片段。 您可以将此类片段添加到 Activity 以保留有状态的对象。

要在运行时配置变更期间将有状态的对象保留在片段中,请执行以下操作:
扩展 
Fragment
 类并声明对有状态对象的引用。
在创建片段后调用 
setRetainInstance(boolean)

将片段添加到 Activity。
重启 Activity 后,使用 
FragmentManager
 检索片段。

例如,按如下方式定义片段:

public class TestFragment1 extends Fragment {
//尽管您可以存储任何对象,但是切勿传递与 Activity 绑定的对象,例如,Drawable、Adapter、View
// 或其他任何与 Context 关联的对象。否则,它将泄漏原始 Activity 实例的所有视图和资源。
// (泄漏资源意味着应用将继续持有这些资源,但是无法对其进行垃圾回收,因此可能会丢失大量内存。)
private MyDataObject data;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment,
setRetainInstance(true);
}

public static  class MyDataObject {
public int type = 0;
public String text = "";
}

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

public MyDataObject getData() {
return data;
}
}


public class MainActivity extends AppCompatActivity {
private TestFragment1 testFragment1;
private TestFragment2 testFragment2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

FragmentManager fm = getFragmentManager();
testFragment1 = (TestFragment1) fm.findFragmentByTag("data");

if (testFragment1 == null) {
//add the fragment
testFragment1 = new TestFragment1();
fm.beginTransaction().add(testFragment1, "data").commit();
testFragment1.setData(loadMyData());
Toast.makeText(this, "the data type orignal is " + testFragment1.getData().type + " and the text orignal is " + <
4000
span style="color:#9876aa;">testFragment1.getData().text, Toast.LENGTH_SHORT).show();

} else {
// the data is available in dataFragment.getData()
TestFragment1.MyDataObject dataObject = testFragment1.getData();
Toast.makeText(this, "the data type is " + dataObject.type + " and the text is " + dataObject.text, Toast.LENGTH_SHORT).show();
}

}

private TestFragment1.MyDataObject loadMyData() {
TestFragment1.MyDataObject object = new TestFragment1.MyDataObject();
object.type = 2;
object.text = "LisaTest";
return object;
}
}


如果只是想在运行时变更截获并且进行自处理,可以进行如下的操作

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">

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

    // Checks the orientation of the screen
    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();
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: