Android - 在 UI Fragment 中保留对象

2023-12-02

在我的项目中,我最初使用的是这个方案:

活动A(UI) > 片段B(非 UI)> 适配器 + AsyncTask

  • B保留与setRetainInstance(true)并更新A UI
  • A实例化B with getFragmentManager()

但我现在需要使用UI Fragments,所以我想到使用这个方案:

活动A> 碎片B(UI) > 片段C(非 UI)> 适配器 + AsyncTask

  • C保留与setRetainInstance(true)并更新B UI
  • B实例化C with getChildFragmentManager()

但这似乎不可能:

Caused by: java.lang.IllegalStateException:
    Can't retain fragements that are nested in other fragments

我尝试实例化C with getFragmentManager()代替getChildFragmentManager()但我遇到了一些问题。


在片段中保留对象和管理异步任务的最佳实践是什么?


我终于开发了一个小助手类:

public class RetainFragment<F extends Fragment> extends Fragment {

    private static <F extends Fragment> String tag(F ui, Object id) {
        return ui.getClass().getName() + id.toString();
    }

    public static <F extends Fragment> Fragment get(F ui, Object id) {
        return ui.getFragmentManager().findFragmentByTag(tag(ui, id));
    }

    public F ui;
    public Object id;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setRetainInstance(true);
    }

    public void link(F ui, Object id) {
        this.id = id;
        this.ui = ui;
        if (get(ui, id) == null) {
            ui.getFragmentManager()
              .beginTransaction()
              .add(this, tag(ui, id))
              .commit();
        }
    }

    public void unlink() {
        if (get(ui, id) != null) {
            ui.getFragmentManager()
              .beginTransaction()
              .remove(this)
              .commit();
        }
        ui = null;
        id = null;
    }

}

现在,在 UI Fragments 中,我只写:

public class UiFragment extends Fragment {

    private static class Retain extends RetainFragment<UiFragment> {
        private MyAsyncTask task;   // Objects to retain over
        private MyAdapter adapter;  // configuration changes
    }

    private Retain retain;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        retain = (Retain) Retain.get(this, 0);
        if (retain == null) {
            retain = new Retain();
            // Retained objects initialization
            retain.adapter = new MyAdapter();
        }
        retain.link(this, 0);
    }

    @Override
    public void onDetach() {
        if (isRemoving()) {
            // Retained objects terminate
            if (retain.task != null) {
                retain.task.cancel(true);
            }
            retain.unlink();
        }
        super.onDetach();
    }

    private void update() {
        if (!isDetached()) {
            // Update UI fragment
        }
    }

}

And in retain.task.onPostExecute():

retain.ui.update(); // Reference to the last ui fragment instance linked

并在 UI 片段启动时启动任务:

private static class Retain extends RetainFragment<UiFragment> {
    private MyAsyncTask task;   // Objects to retain over
    private MyAdapter adapter;  // configuration changes

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        ui.onRetainCreated();
    }
}

private void onRetainCreated() {
    retain.task = new MyAsyncTask() {
        @Override
        protected void onPostExecute(Void result) {
            retain.ui.update();
        }
    };
    retain.task.execute();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android - 在 UI Fragment 中保留对象 的相关文章

  • BottomNavigationView - 如何获取选定的菜单项?

    我使用BottomNavigationView来切换片段 如何获取当前选定的菜单项 以防止重新打开片段 BottomNavigationView bottomNavigationView BottomNavigationView findV
  • Android 通知进度条冻结

    这是我正在使用的代码 http pastebin com 3bMCKURu http pastebin com 3bMCKURu 问题是 一段时间后 文件变得更重 通知栏下拉速度变慢 最后它就冻结了 你的通知太频繁了 这就是它冻结的原因 让
  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • Android - 如何一次只允许播放一个 MediaPlayer 实例?

    我正在尝试创建一个简单的 Sound board Android 应用程序 使用 ListView 项目作为按钮 顺便说一句 我是一个新手程序员 我的想法是 我按下一个按钮 就会播放一个特定的声音文件 如果我在播放声音时按下任何按钮 它应该
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • Firebase Analytics 禁用受众国家/地区跟踪

    我正在开发一个严格不允许位置跟踪的应用程序 我想使用 Firebase Analytic 的其他功能 例如 PageTransitions 和 Crashalitics 但如果我无法禁用受众位置跟踪 我就无法使用其中任何功能 这是我在 An
  • 如何从 SQLite 获取记录总数

    我正在尝试从 Sqlite DB 获取行的总数 以下是我想要做的代码片段 我不知道我在这里做错了什么 public static int getTotalCount Context context Cursor c null try c g
  • Phonegap - 如何将.txt文件保存在Android手机的根目录中

    我正在尝试使用phonegap 将 txt 文件保存在Android 手机的根目录中 我已经安装了这些插件 cordova plugin file 和 cordova plugin file transfer 在 config xml 文件
  • Delphi XE7 Android 全屏(隐藏软键)

    如何在XE7中全屏显示 隐藏顶部 标题 和底部 软键 工具栏 在 XE6 中 我可以通过在应用程序部分写入来调整 AndroidManifest 以使我的应用程序全屏显示并且没有操作栏 android theme android style
  • RxJava、Proguard 和 sun.misc.Unsafe

    我有以下问题RxJava 1 1 0 使用时Proguard 我没有更改 RxJava 版本或其 pro文件 但更新后OkHttp我无法编译使用Proguard因为我有关于sun misc Unsafe不在场 rxJava pro keep
  • 接近语法错误(代码1)插入Android SQLite

    我正在创建一个通讯录应用程序 用户可以在其中输入姓名 电子邮件地址和号码 我希望将此数据保存在数据库中 但我似乎无法使插入方法起作用 我收到的错误是 android database sqlite SQLiteException near
  • 设置从 Facebook 登录获取用户电子邮件 ID 的权限

    我在用着Facebook 3 0 SDK对于安卓 我必须实施Facebook登录 我正在访问用户的基本信息 例如姓名 用户 ID 但我也想访问用户的电子邮件 我浏览了很多博客和论坛 但不知道该怎么做 我正在使用我自己的 android 按钮
  • 如果我们使用后退按钮退出,为什么 Android 应用程序会重新启动?

    按住主页按钮并返回应用程序时 应用程序不会重新启动 为什么使用后退按钮会重新启动 如果我们使用后退按钮退出 有什么方法可以解决在不重新启动的情况下获取应用程序的问题吗 请帮忙 当您按下Home按钮 应用程序将暂停并保存当前状态 最后应用程序
  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • 在我的Android中,当其他应用程序想要录制音频时如何停止录音?

    在我的应用程序中 服务通过 AudioRecord 持续录制音频 当我的应用程序运行时 其他与音频记录相关的应用程序 例如 Google 搜索 无法工作 如何知道何时有其他应用想要录制音频 以便我可以停止录制以释放资源 答案是MediaRe
  • 更新到材质 1.2.0 后,材质按钮上缺少圆角半径属性

    这是我的材质按钮代码
  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • Android 设备上的静默安装

    我已经接受了一段时间了 在 Android 上静默安装应用程序是不可能的 也就是说 让程序安装捆绑为 APK 的应用程序 而不提供标准操作系统安装提示并完成应用程序安装程序活动 但现在我已经拿到了 Appbrain 快速网络安装程序的副本

随机推荐

  • 从多个表中选择语句,具有可变输入

    我有两张桌子 AreaCode and EquipmentNumber AreaCd AreaID INT NOT NULL AUTO INCREMENT Code INT Name CHAR 30 Comments TEXT PKEY A
  • 密钥在 pm3d gnuplot 中变得不可见

    我正在使用以下代码使用 pm3d 地图在 gnuplot 中绘制图形 set pm3d map set pm3d corners2color c1 spl patternD0pt02 dat title a 但是当生成图时 本来应该出现在右
  • 使用注释的 Spring Integration Executor Channel 代码示例

    附上我的系统图 系统图 流程如何运作 spring 集成流程从 C 上的 json 文件读取输入并执行 2 个操作 存入数据库 通知 打印给用户 重要标准 我希望存储到数据库流中独立于业务逻辑 打印到 通知用户 即数据库exception
  • 应用程序被终止后 Android 服务停止

    我想创建一个service即使应用程序从任务管理器关闭 它也会运行 我创建了一个服务 然后记录一条消息以检查它是否正在运行 我注意到它仅在应用程序正在运行或在前台运行时才有效 服务等级 public class CallService ex
  • 具有多选下拉菜单的数据表特定列过滤器

    我在 Datatable API 中看到了这种可能性 可以使用 Drop down 进行特定列过滤 Ref https datatables net examples api multi filter select html 但对我来说 它
  • Android 上的浮动应用程序(窗口应用程序)

    有谁知道如何创建浮动窗口 下图显示了我的意思 源代码 我在各种网站上读到 为了做到这一点 应用程序必须作为服务运行 而该服务又应该使用 TYPE SYSTEM ALERT 作为活动运行 如果上述是或不是真的 我仍然不知道如何实现代码 有人可
  • 使用 python 缓慢上传到 azure blob 存储

    Api 接收文件 然后尝试创建唯一的 blob 名称 然后我将 4MB 的块上传到 blob 每个块大约需要 8 秒 这正常吗 我的上传速度是110Mbps 我尝试上传一个 50MB 的文件 花了将近 2 分钟 我不知道azure blob
  • 如何使用ajax保存到数据库

    我有一个工作正常的代码 但数据无法保存到数据库 我想通过 Ajax 将 cost currency rate profit rate 和 pprice 插入数据库 这是javascript和update php的代码 我尝试修改代码以保存在
  • 如何使用批处理文件分割字符串?

    如何使用批处理脚本分割字符串 设置java path C Program Files Java jdk1 6 0 31 上面是我的字符串 我只想要 java path 中的 C Program Files 如何得到它 您可以按字符位置拆分字
  • 使用 Log4j 的每个用户都有不同的日志

    我有一个 Web 应用程序 我想为每个用户使用不同的日志 这样我就可以获得用户在系统上执行的操作的 历史记录 这是我到目前为止所拥有的 import java io File import java io IOException impor
  • 将单词列表转换为数组[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 我试图查看是否有任何脚本可以将单词列表转换为数组 但我似乎找不到 有人知道我在哪里可以找到一个吗 Input Dog Cat Hamster 转换为 Dog Cat Hamster 不
  • cURL 错误 58:SSL:无法加载证书“...”及其私钥:Mac 上的 OSStatus -25299

    该代码在 Ubuntu vagrant box 上运行良好 但在本地 MacO 上它不会加载证书 说 cURL error 58 SSL Can t load the certificate and its private key OSSt
  • 如何像矩阵乘法一样将行向量添加到列向量

    我有一个 nx1 向量和一个 1xn 向量 我想以一种特殊的方式添加它们 例如以有效的方式 矢量化 矩阵乘法 Example A 1 2 3 B 4 5 6 A odd add B 1 4 1 5 1 6 2 4 2 5 2 6 3 4 3
  • 命名空间::变量的多重定义,甚至使用 ifndef

    我知道我在这里一定做错了什么 rank h ifndef RANK H define RANK H namespace mmi int chunk void rank int my rank endif rank cpp include r
  • 如何检测 Python 是否作为 64 位应用程序运行? [复制]

    这个问题在这里已经有答案了 我正在对 Windows 注册表进行一些工作 根据 Python 运行为 32 位还是 64 位 某些键值会有所不同 如何检测 Python 是作为 64 位应用程序运行还是作为 32 位应用程序运行 我对检测
  • 在悬停时添加边框时如何防止移动? (透明边框不是解决方案)[重复]

    这个问题在这里已经有答案了 我想在悬停时为 div 添加边框 但是添加边框时 div 稍微有点拉屎 这是一个众所周知的问题 常见的解决方案是添加透明边框 例如 但是 我的 div 中有一张包含一些文本的图像 我希望该图像占据 div 的全宽
  • 正则表达式西班牙语和阿拉伯语单词

    如何编写匹配所有有效的西班牙语和阿拉伯语单词的正则表达式 用我知道的英语来说 它是a zA z 在希伯来语中是 俄语 我使用 JavaScript 范围a zA Z因为英语单词的简单和天真令人难以接受 它省略了所有带有重音符号的字母以及在借
  • 过渡到 vim。存在缩进问题

    我正在从手术中恢复 因此 我正在过渡到 VIM 作为起点 我选择使用 vim sensible 插件作为我的配置的基础 此外 我还安装了 vim rails 和 vim ruby 插件 这些都是通过 Pathogen 加载的 无论出于何种原
  • 序列化 JFrame 并通过网络发送

    我想做的是通过套接字发送 JFrame 问题是在我发送表格并按下按钮查看它之后 我得到以下异常 package ds3 import java io IOException import java io ObjectInputStream
  • Android - 在 UI Fragment 中保留对象

    在我的项目中 我最初使用的是这个方案 活动A UI gt 片段B 非 UI gt 适配器 AsyncTask B保留与setRetainInstance true 并更新A UI A实例化B with getFragmentManager