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

2023-11-26

我有一个FragmentActivity显示联系人列表。

这是我的onCreate method:

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

My 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, displayName, 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为null的原因是——系统只保存由于系统限制而被破坏的活动的状态。如果您退出 Activity,它将被永久销毁,并且不会保存任何状态。

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

当您的 Activity 由于用户按 Back 或 活动自行完成,系统对该活动的概念 实例永远消失了,因为行为表明了活动 不再需要。但是,如果系统由于以下原因破坏了该活动 系统约束(而不是正常的应用程序行为),那么尽管 实际的 Activity 实例消失了,系统会记住它 存在,如果用户导航回它,系统会创建 使用一组已保存数据的活动的新实例 描述活动被销毁时的状态。

因此,您的特殊问题似乎是,当您的 Activity 消失时,您的静态 HumanContact 类仍在内存中,并且您的新 Activity 正在加载您的联系人的另一个副本。

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

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

HumanContent 似乎已经在一定程度上承担了这一责任。您使用它来存储数据,并且它会在您的 Activity 的生命周期之外持续存在。您还可以向其中添加一个方法来检查是否已加载联系人,如果没有则自行加载。这样,它就可以完全控制数据的加载和缓存,并且“活动”可以单独负责此数据的显示。使用这种类型的解决方案时要小心,不要在内存中存储太多数据,只要您预计数据发生更改,就会重新加载缓存,并注意在某些情况下系统可能会重新启动您的进程,因此您的缓存必须准备好重新加载数据,以防数据被破坏。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • onActivityResult 中的完成活动不起作用

    我有一对必须同生共死的活动 基本上 AlphaActivity 会做一些工作 然后发送一个意图 startActivityForResult 对于 Beta 活动 当 Beta 活动完成时 我希望它发送一个意图 startActivity
  • Android - 如何访问 onResume 中 onCreate 中实例化的 View 对象?

    In my onCreate 方法 我正在实例化一个ImageButton View public void onCreate Bundle savedInstanceState super onCreate savedInstanceSt
  • 检查双精度值的等于和不等于条件

    我在比较两者时遇到困难double values using and 我创建了 6 个双变量并尝试进行比较If健康 状况 double a b c d e f if a b c d e f My code here in case of t
  • android 谷歌+登录定制

    我正在创建一个 Android 应用程序 现在我正在实现社交网络登录 Facebook 按钮很好 但 google 按钮的语言与 Facebook 不同 另外 它只说 登录 我想让它说 用谷歌登录 我是 android 编程的新手 看到我需
  • 无法解析符号 FlutterActivity

    我使用 VCS gt Checkout from Version Control 将 flutter 项目从 github 导入到 Android Studio 中 现在我面临的问题是 Cannot resolve symbol Flutt
  • 无法合并 Dex - Android Studio 3.0

    当我在稳定频道中将 Android Studio 更新到 3 0 并运行该项目时 我开始收到以下错误 Error Execution failed for task app transformDexArchiveWithExternalLi
  • 更改 AChartEngine 中的图例大小

    我想专门更改饼图的图例大小输出 我已经尝试了所有可以找到的 AChartEngine 方法 但没有一个只能更改图例文本大小 我必须重写 onDraw 函数吗 如果是这样 怎么办 要设置图例高度 请使用 renderer setLegendH
  • 将标题设置为操作栏时出现空指针异常

    Error Caused by java lang NullPointerException Attempt to invoke virtual method void android app ActionBar setTitle java
  • OpenCV InRange 参数

    我在 Android 上使用 OpenCV 来实时查找特定颜色的圆圈 我的第一步是仅保留与我正在寻找的定义颜色相对应的像素 在本例中为红色或绿色 示例图像 https i stack imgur com CIozU jpg 为此 我正在使用
  • layout.xml 的用途是什么?

    人们为什么使用layout xml在他们的resources like
  • Cordova 地理定位不适用于 Android

    我想在 Android 上使用地理定位 我用 Apache Cordova 编写应用程序 地理定位在 android 电脑模拟器和 android 手机上均不起作用 I try http cordova apache org docs en
  • 我们可以在 android studio 中拥有没有 app 文件夹的项目,并将所有内容(java/res/etc)放在根目录中吗

    我想知道在 Android studio 中是否可以有没有应用程序模块 应用程序或任何其他名称 的 android 项目 意味着我可以在项目本身的根目录中创建包和资源 而不是使用应用程序模块 编辑 结构看起来像 MyApp idea gra
  • 在 Android 中使用 iText 读取或打开 PDF 文件

    我是 Android 应用程序开发新手 使用 iText 我完成了 PDF 创建并在创建的文件上写入 现在我想阅读该 PDF 文件 如何使用 iText 打开或阅读 PDF 文件 例子将是可观的 那么提前 哪个是渲染 PDF 文件的最佳库
  • 版本 5 上带有 getBackground().setAlpha 的按钮 - 棒棒糖无法正常工作

    我有这段代码 适用于自 API 14 以来的每个版本 但在 Android 5 0 Lollipop 上无法正常工作 以下是我希望按钮出现的方式 单击按钮1 buttonArrivals getBackground setAlpha 180
  • 当应用程序未运行时如何堆叠 Firebase Cloud Messaging 通知?

    我在用Firebase Cloud Messaging将推送通知从我的服务器发送到我的 Android 应用程序 当应用程序运行时 通知是stacked因为我将它们设置为我的一个组FirebaseMessagingService 这很好 但
  • 手动启用时 Firebase Crashlytics 不报告崩溃

    Crashlytics 在没有选择加入报告的情况下也能正常工作 但一旦我根据规定设置了选择加入报告 它就会停止报告任何内容tutorial https firebase google com docs crashlytics customi
  • 如何从SurfaceView绘制到Canvas?

    我正在尝试做简单的画家 问题是Android看起来有三个独立的Canvas并给我它来顺序绘制 我用以下方式制作了用户界面SurfaceView 把霍尔德从中拿走 Override protected void onCreate Bundle
  • 点击监听器的公共类

    我的所有 6 项活动中有 7 个按钮 所有 6 个按钮在所有活动中都具有相同的功能 如何为这 6 个按钮执行通用的单击事件侦听器 您可以创建一个实现 View OnClickListener 的新类 如下所示 public class My
  • 带有空白白屏的 WebView

    我在 DialogFragment 中有一个 webview 它使用以下方式显示文档和 PDF它可以进行几次尝试 但如果用户尝试频繁打开和关闭对话框 webview 将显示空白屏幕 我已经尝试了所有的线程link1 https stacko
  • 修改 ADW Android 启动器?

    我想更改和修改开源 ADW 启动器 启动器可在此处获取 https github com AnderWeb android packages apps Launcher https github com AnderWeb android p

随机推荐