【问题标题】:MainActivity does not update after coming back from different activityMainActivity 从不同的活动回来后不更新
【发布时间】:2015-08-02 03:57:40
【问题描述】:

我有两个活动,一个 MainActivity 和一个辅助活动(例如:关于屏幕),然后我有一个 asynctask 来更新 MainActivity 上的 UI。这部分工作正常,异步任务通过调用 MainActivity 中的一个方法来更新 UI,该方法使 UI 膨胀并设置一些值。此方法还使所有 UI 组件可见。

不工作的是,在转到 About 屏幕并返回 MainActivity 后,UI 完全是空白的。我不明白为什么在从其他活动返回后停止工作,否则工作正常。

有人可以建议吗?

这是我绘制 UI 的方式。这就是我从线程更新它的方式,它可以工作,直到我进入关于屏幕:

private void DisplayMainContent()
{
    Context context = Util.DataStruct.LoadContext();
    Log.d("debug", "DisplayMainContent() loaded a context " + context.toString());

    RelativeLayout parent = (RelativeLayout)((Activity)context).findViewById(R.id.action_settings);
    LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = li.inflate(R.layout.activity_main, parent);

    TextView version = (TextView) v.findViewById(R.id.latestVerField);

    version.setText(Util.DataStruct.GetVal("version")); 
}

【问题讨论】:

  • 你能添加你的代码吗?
  • 你能发布你的代码吗?尤其是onCreate、onPause; onResume 等

标签: android


【解决方案1】:

关于消失数据的小故事..

  1. 建议:

    • 不要使用新的活动来实现这一点 - 将你的关于作为对话框或对话框片段

    nice example how to show dialog using fragment

    • 不要使用静态 - 而是使用单例模式

    Singleton 保留了传统的类方法,并且不需要您在任何地方都使用 static 关键字。一开始它们可能对实现要求更高,但会大大简化程序的体系结构。与静态类不同,我们可以使用单例作为参数或对象。此外,您可以像使用任何其他类一样将单例与接口一起使用。

  2. 我发现问题的地方:

    这一行是你需要追踪你的错误: (我认为你代码的任何其他片段都与你的问题无关)

version.setText(Util.DataStruct.GetVal("version"));
  1. 解释原因:

    Util.DataStruct:

    • 应该是单例,并具有有效的硬引用,例如。在应用程序类或任何其他寿命更长的活动中,你用来显示数据。

    你知道垃圾收集器的存在吗?

    我想指出什么? 为什么要避免静电!?

    代码(数据)流程:

    1. 应用启动 - 初始化静态类/变量等
    2. 您的变量是 feed(通过异步或其他方式)
    3. 您的应用已被 ANDROID OS 关闭 - 不管是什么原因
    4. os 重新创建“堆栈”
    5. 但不是 yr 变量 - 它们是空/null/默认值 - 不被值引用,因为它们应该在正常代码流中

    上下文:

    你从哪里使用你的 DisplayMainContent() ?你需要什么上下文?

    • 对于需要它的应用方法,上下文应该是“锚”。 (这就像某些安全性的东西 - “嗨,这个应用程序片段属于我,我有权修改和查看内容 - 所以做任何 stuuf 你传递你最近的上下文 - 从片段活动对话框小部件等”)

    • 如果你可以使用 getContext() 例如。 ("from parent") - 不要使用任何静态的

    示例:

    • 在片段中:
  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        Context context = container.getContext();
    }
  • 在适配器中:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
        Context context = parent.getContext();
}

关于通货膨胀 - 使用:

 LayoutInflater.from(context).inflate(res,ViewGroup,attachToRoot);
  • 你在通货膨胀中使用父级吗(在片段中,你在活动中使用怀疑)

对于@bcorso:

不要使用超出您需要的资源。

@TomaszBest 抱歉,但你真的不知道你在说什么 about: Util.DataStruct.GetVal() 正在调用的静态方法 静态类 Util.DataStruct,因此必须返回一个静态类 多变的。静态类变量是单例的(只有一个会是 创建),它不会被垃圾收集。

通过静态成员变量引用的对象被强引用,直到类被卸载。普通的 ClassLoader 从不卸载类,但应用程序使用的类在正确的条件下会这样做。

如果更改静态字段以引用不同的对象,则 静态字段指向的原始对象与任何其他对象一样有资格进行 GC!

静态变量的初始化在 Section 2.11 Static Initializers of suns JVM spec. 规范中没有定义垃圾回收的实现 - 静态对象的垃圾回收规则将根据您的 VM 有所不同。

总之:

如果你的类永久持有这个对象,它只会在 vm 退出时被释放。只有引导加载程序加载的类和接口可能不会被卸载。

【讨论】:

  • 虽然这可能是您选择的编码风格,但它并不能回答问题。至少,解释一下为什么你认为在 OP 的情况下使用新的 Activity 是个坏主意。
  • @bcorso 这不是我的预期编码风格 - 有多少人在第一个房子旁边建造新的“第二个”房子只是为了使用浴室?或者你在第一个浴室里建第二个浴室? - 这是浪费资源!
  • 这不是预期的。 Android 中有许多有效的编码风格,包括根本不使用 Fragment(Square 的人就是这样做的)、有单个 Activity 和许多 Fragment,或者有多个 Activity 和多个 Fragment。
  • 另外,将 TextView 的文本设置为静态变量如何导致内存泄漏?以及如何将所有这些移入 Fragment 来修复内存泄漏?
  • 不是问题的答案,你指出了Util.DataStruct.GetVal("version"),而我看到了更可疑的Util.DataStruct.LoadContext()。从静态加载的上下文,但不知道它是如何在幕后工作的,它仍然是可疑的。顺便说一句,现在越来越多的人认为碎片是个坏主意。阅读那篇文章:corner.squareup.com/2014/10/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多