【问题标题】:Accessing MyApplication from android fragments从 android 片段访问 MyApplication
【发布时间】:2013-06-12 20:37:05
【问题描述】:

基本上,我开始将纯活动应用程序移植到片段,但我几乎被困在第一步。

在我当前的应用程序中,我扩展了应用程序以访问用于自定义应用程序的全局常量和变量。

public class MyApplication extends Application {
    private final int nbreLivres = 50;
    private final String[] nomsLivres = new String[nbreLivres];

    private final int colorCount = 25;
    private final int[] customColors = new int[colorCount];

    private SparseIntArray hmColors = new SparseIntArray();

    private int mCustomFontSize = 14;

    private static MyApplication instance;

    ...
    ... 

    public int getColorCount() {
        return colorCount;
    }

    public int getColorFromIndex(int index) {
        return customColors[index];
    }

    ...
    ...
    ...
}

从我做类似的活动中访问它

((MyApplication) this.getApplication()).getColorCount();

如果我需要使用实例访问它,我会这样做

private MyApplication mApp = MyApplication.getMyApplication();
mApp.getColorCount();

问题:

在 Fragment 中执行这些操作时,例如设置列表 (ListFragment) 的值以列出我的应用程序中可用的所有颜色

((MyApplication) getActivity().getApplication()).getColorsList();

我也试过了

MyApplication.getMyApplication().getColorsList();

两者都只是在该行崩溃并出现“空指针”异常。

我有什么不明白或我做错了什么?

编辑

抱歉,我忘记提及它基于 Eclipse 中给出的主/详细示例,我尝试用我自己的数据填充主列表。

在这里(我没有复制/粘贴所有无用的东西)。

public class LivreListFragment extends ListFragment {

    ...
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setListAdapter(new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_list_item_activated_1,
            android.R.id.text1, ((MyApplication) getActivity().getApplication()).getColorsList() ));
    }
}

回答

最后我发现我忘记在清单文件中定义我的应用程序名称了!

现在我的代码可以正常工作了。

但是根据@CharlieCollins 的回答,我必须将它放在 onActivityCreated 中,而不是放在 onCreate 中(不安全)。

感谢您的帮助,了解 onActivityCreated 的重要性。

【问题讨论】:

  • 好吧,您说它与 NPE 一起崩溃,因此查看您的片段代码(实际上使应用程序崩溃)可能会有所帮助;-)

标签: android fragment


【解决方案1】:

好的,这就是我所做的:

自定义应用程序

public class MyApplication extends Application {

    public int getColorCount() {
        return 1;
    }
}

自定义活动

public class MainActivity extends Activity {

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

        getFragmentManager().beginTransaction().add(R.id.container, new TestFragment()).commit();
    }
}

自定义片段

public class TestFragment extends Fragment {

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        int test = ((MyApplication) getActivity().getApplication()).getColorCount();
        Log.d("testfrag", "" + test);
    }
}

它会按预期打印出“1”。
现在我不知道您是否可以仅在此示例旁边编写代码并自己在代码中找到问题,那当然很棒。 如果不是,那么我想我们需要的是逐步从您的应用中获取更多详细信息、您的片段实现、日志输出等。

备注

概述了上述实现以在完全创建托管活动时检索它。这可能因应用程序而异:

  • 如果您只想将活动作为对象访问,请使用 onAttach 回调
  • 如果您想访问完全创建的活动,请使用onActivityCreated 回调

这是两个不同的用例,您应该始终了解自己的需求

【讨论】:

  • 感谢您的回答。我在此基础上开始调试,它帮助了我。然而,根据查理柯林斯的说法,在 onCreate 中调用它是“不安全的”。
  • 绝对正确,我只是想让我的版本尽可能接近您的版本,同时仍然功能齐全。有关片段生命周期的更多知识,请参阅here。然后你可以自己做出有根据的决定:)如果你需要更多帮助,请告诉我,如果不需要,我会很感激接受。问候
  • @avalancha 即使您的答案有效,但它是不安全的。我了解您想回答接近我的问题,但我在 onCreate 中这样做是错误的。对于未来的读者,编辑您的答案以使用 onActivityCreated 而不是 onCreate ,然后我将接受答案作为“正确”答案。顺便谢谢你的帮助。
【解决方案2】:

Android: Fragment cannot get activity

基本上,您可能试图在Fragment 生命周期的错误时间点访问Activity。确保您只在onActivityCreated 期间或之后尝试访问Activity。 (我说可能是因为没有代码就无法判断。如果这不是问题,请显示更多Fragment 代码。)

【讨论】:

  • 这可能是正确的答案,但它有一个小缺陷:您应该始终访问onAttach 回调中的活动!这是 android 推荐的,并用于各种推荐的模式(例如,对主机活动的片段回调)。 onAttach 保证是第一个调用,并且将活动作为参数
  • 与 onAttach 和 onActivityCreated 的区别在于,根据设计和定义,onActivityCreated 是在操作完成 onCreate 之后调用的 frag 生命周期中的第一个方法。您不应该将 onAttach 用于需要创建该行为的内容。 (您提到的回调示例模式不同,这与行为的生命周期无关。)请参阅文档:developer.android.com/guide/components/…
  • @HpTerm,您编辑的问题证实了我的回答。您试图在“onCreate”中调用“getActivity”。你不能安全地做到这一点。请参阅此处的答案以及链接的文档。
  • @CharlieCollins,首先感谢您的回答。我已经仔细阅读了您的回答,并根据您的回答阅读了一些文档。如果我错了,请纠正我。问题是我尝试在创建活动之前访问片段所在的活动。所以我试图将我的 setListAdapter 放在 onActivityCreated 的覆盖中。但它仍然与 NPE 崩溃。我正在调查原因。另一点是,根据您的说法,为什么雪崩的例子有效?他不应该把代码放在 onActivityCreated 吗?
  • 好的,我的代码已经启动并运行了。我太笨了。我只是忘记在清单文件中定义我的应用程序名称!现在我尝试将我的代码放在 onCreate 和 onActivityCreated 中。两者似乎都有效。但是你建议我把它放在 onActivityCreated 中对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 2021-06-25
  • 2012-10-15
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
相关资源
最近更新 更多