如何避免在Android上的onCreate上重新创建视图?

前端之家收集整理的这篇文章主要介绍了如何避免在Android上的onCreate上重新创建视图?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个显示联系人列表的FragmentActivity.

这是我的onCreate方法

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

    if (findViewById(R.id.human_detail_container) != null) {
        // The detail container view will be present only in the
        // large-screen layouts (res/values-large and
        // res/values-sw600dp). If this view is present,then the
        // activity should be in two-pane mode.
        mTwoPane = true;

        // In two-pane mode,list items should be given the
        // 'activated' state when touched.
        ((HumanListFragment) getSupportFragmentManager()
                .findFragmentById(R.id.human_list))
                .setActivateOnItemClick(true);
    }

    if (savedInstanceState == null || !savedInstanceState.getBoolean("displayed_contacts"))
        displayContacts();
}

我的onSaveInstanceState:

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putBoolean("displayed_contacts",true);
}

而且我不确定这是否相关,但这是我的displayContacts以防万一:

private void displayContacts() {

    // Init variables
    String[] SelectColumns = new String[] { Contacts._ID,Contacts.DISPLAY_NAME_PRIMARY,Contacts.PHOTO_URI };
    String rawContactID,displayName,phoneNumber;
    InputStream thumbnailPhoto;
    Cursor c,infoC;

    // Outer cursor (fetches all contact IDs)
    c = getContentResolver().query(
            Contacts.CONTENT_URI,SelectColumns,Contacts.HAS_PHONE_NUMBER + " = 1 ",null,Contacts.DISPLAY_NAME_PRIMARY);

    Log.v(getPackageName(),"Found " + (c != null ? c.getCount() : "0") + " contacts");
    try {
        if (c.moveToFirst()) {
            do {
                // Columns
                rawContactID    = c.getString(c.getColumnIndex(SelectColumns[0]));
                displayName     = c.getString(c.getColumnIndex(SelectColumns[1]));
                String[] selectPhone = {CommonDataKinds.Phone.NUMBER};

                thumbnailPhoto = openThumbnail(Long.valueOf(rawContactID));

                infoC = getContentResolver().query(
                        CommonDataKinds.Phone.CONTENT_URI,selectPhone,CommonDataKinds.Phone.CONTACT_ID + " = ?",new String[] {rawContactID},null
                    );
                infoC.moveToFirst();
                phoneNumber = infoC.getString(0);

                // Adds items to ListView
                HumanContent.addItem(new HumanContent.HumanItem(rawContactID,phoneNumber != "n/a" ? phoneNumber : "",thumbnailPhoto));
                Log.v(getPackageName(),"Cursor position: " + c.getPosition() + ",contact ID: " + rawContactID);
                infoC.close();
            } while (c.moveToNext());
            c.close();
        }
        displayed_contacts = true;
    } catch (Exception e) {
        Log.e(getPackageName(),e.getMessage());
    }
}

现在是这样的:

当我使用后退键退出应用程序,然后通过图标再次打开它时;即使列表保存在内存中,列表也会重新创建:所以我在同一视图中获得了一个双重联系人列表.

在这种情况下,savedInstanceState为null,因此达到了if条件,但实际上该视图已经有了我之前的联系人列表.是什么赋予了?如何避免重新创建列表?我已经尝试过使用实例变量,但无济于事.

我还想避免100%重复列表 – 如果我可以重用现有的视图,真棒.

解决方法

首先,您的savedInstanceState为空的原因 – 系统仅保存由于系统约束而被销毁的活动的状态.如果退出活动,它将被永久销毁,并且不会保存任何状态.

相关文档:@H_404_27@http://developer.android.com/training/basics/activity-lifecycle/recreating.html

When your activity is destroyed because the user presses Back or the@H_404_27@ activity finishes itself,the system’s concept of that Activity@H_404_27@ instance is gone forever because the behavior indicates the activity@H_404_27@ is no longer needed. However,if the system destroys the activity due@H_404_27@ to system constraints (rather than normal app behavior),then although@H_404_27@ the actual Activity instance is gone,the system remembers that it@H_404_27@ existed such that if the user navigates back to it,the system creates@H_404_27@ a new instance of the activity using a set of saved data that@H_404_27@ describes the state of the activity when it was destroyed.

因此,看起来您的特定问题是,当您的Activity消失时,您的静态HumanContact类仍然在内存中,而您的新Activity将使用另一个联系人副本加载它.

有几种方法可以解决这个问题.首先,您可以在HumanContent上实现一个方法来清除其所有项目,并在您启动Activity的新实例时调用它.这样可以确保您的数据是最新的,但这意味着您必须重新加载您的联系人.

其次,如果你想真正避免重新加载数据,我建议为独立于Activity的联系人创建某种缓存.您应该将Activity视为相当短暂的,它可以并且将被频繁地销毁和重新创建,而缓存可以持久存在.

HumanContent似乎已经在某种程度上填补了这一责任.您正在使用它来存储您的数据,并且它会持续超出您的Activity的生命周期.您还可以向其添加一个方法,以检查是否已加载联系人,如果没有加载它们本身.这样,它就可以完全控制加载和缓存数据,而活动只能负责显示这些数据.请注意这种类型的解决方案,即您没有在内存中存储太多数据,而是在您希望数据发生更改时重新加载缓存,并注意在某些情况下系统可能会重新启动您的进程,因此您的缓存必须准备好重新加载您的数据,以防它被销毁.

至于保留您的视图,如果用户退出您的Activity,则调用finish(),并且您的Activity将被销毁.请记住,在这种情况下,系统不再具有Activity的任何概念,因此无法保留这些视图以供重用.

猜你在找的Android相关文章