草庐IT

java - onresume 后 ViewPager 中的 fragment 为空

coder 2023-12-01 原文

我正在编写一个在其 MainActivity 中有 2 个选项卡的应用程序。我使用适用于 Eclipse 的 Android 插件创建了 Activity 模板并对其进行了调整。 无论如何,当我在一段时间后恢复应用程序时, fragment 将为空。

这是我的 Activity 代码(我删除了“不重要”的部分)

public class MainActivity extends FragmentActivity implements
    ActionBar.TabListener {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a
 * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
 * will keep every loaded fragment in memory. If this becomes too memory
 * intensive, it may be best to switch to a
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
SectionsPagerAdapter mSectionsPagerAdapter;

private static final String ARG_SECTION_NUMBER = "section_number";

/**
 * Fragment to display markets on a {@link GoogleMap}.
 */
private GluehweinMapFragment mGluehweinMapFragment;

/**
 * Fragment to display available markets as list.
 */
private GluehweinListFragment mGluehweinListFragment;


/**
 * The {@link ViewPager} that will host the section contents.
 */
ViewPager mViewPager;



/*
 * (non-Javadoc)
 * 
 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    setContentView(R.layout.activity_main);


    initSectionsPagerAdapter();
//[...]

}

private void initSectionsPagerAdapter() {
    if (mSectionsPagerAdapter == null || mViewPager == null) {
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        // Create the adapter that will return a fragment for each of the
        // three
        // primary sections of the app.
        mSectionsPagerAdapter = new SectionsPagerAdapter(
                getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager
                .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        switch (position) {
                        case 0:
                            break;

                        }
                        refreshFragments();
                        actionBar.setSelectedNavigationItem(position);
                    }
                });
        actionBar.getSelectedNavigationIndex();

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title
            // defined by
            // the adapter. Also specify this Activity object, which
            // implements
            // the TabListener interface, as the callback (listener) for
            // when
            // this tab is selected.
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }
    }
}



/**
 * Hides or shows the closed markets on the list and map
 */
private void updateVisibility() {
    if (this.mGluehweinMapFragment != null) {
        mGluehweinMapFragment.updateVisibility();
    }
    if (this.mGluehweinListFragment != null) {
        mGluehweinListFragment.updateVisibility();
    }
}

@Override
public void onTabSelected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {

    mViewPager.setCurrentItem(tab.getPosition());
    invalidateOptionsMenu();
}

@Override
public void onTabUnselected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
}

@Override
public void onTabReselected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a DummySectionFragment (defined as a static inner class
        // below) with the page number as its lone argument.
        Fragment fragment = null;

        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, position + 1);

        switch (position) {
        case 0:
            // position 0 is the Map
            if (mGluehweinMapFragment == null) {
                mGluehweinMapFragment = new GluehweinMapFragment();
            }
            fragment = mGluehweinMapFragment;
            break;
        case 1:
            // position 1 is the List
            if (mGluehweinListFragment == null) {
                mGluehweinListFragment = new GluehweinListFragment();
            }
            fragment = mGluehweinListFragment;
            break;
        }
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
        case 0:
            return getString(R.string.tab_map).toUpperCase(l);
        case 1:
            return getString(R.string.tab_list).toUpperCase(l);
        }
        return null;
    }

}

@Override
protected void onResume() {
    // on resume, restart requesting location updates
    super.onResume();
    //[..]
    initSectionsPagerAdapter();
    //some calls on the fragments which are null here!!!
    refreshFragments();
}



/**
 * Notifies the Fragments in the Tabs that data has changed
 */
private void refreshFragments() {
    if (this.mGluehweinMapFragment != null) {
        mGluehweinMapFragment.updateVisibility();
    }
    if (this.mGluehweinListFragment != null) {
        mGluehweinListFragment.updateVisibility();
    }
}   

 }

我问了一个同事,他说我的Activity 中保留这两个 Fragments 作为成员是不好的,因为 Android 最终会创建一个 Fragments 的新实例 onResume,这就是为什么我的引用为空。但他无法告诉我如何解决我的问题。 我正在考虑编写一个 getFragment() 方法,该方法将使用 FragmentManager 来获取 fragment ,但我不知道如何让我的 fragment 处于某个状态,其中我可以使用 FragmentManager 阅读它们。

提前致谢!

最佳答案

您的同事是对的:在您的 Activity 变量中使用对 fragment 的引用不是一个好习惯。您的 Activity 将被破坏,例如当您旋转屏幕时,引用可能会导致内存泄漏。

至于您的问题,将初始化 ViewPager 的代码(您的 initSectionsPagerAdapter() 方法)移动到 onResume。它会在 Activity 首次启动时以及它变得可见时被调用,例如当位于顶部的另一个应用程序关闭时。您不需要 onResume 中的当前代码。

编辑:

当您创建一个 fragment 时,不要将对它的引用存储在 Activity 的变量中。稍后要访问 fragment ,您可以使用:

FragmentManager fm = this.getFragmentManager();
GluehweinMapFragment f1 = (GluehweinMapFragment)fm.getFragments().get(0); // to get one fragment

for (Fragment f : fm.getFragments()) { // to loop through fragments and checking their type
    if (f instanceof GluehweinMapFragment) {
    }
}

关于java - onresume 后 ViewPager 中的 fragment 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20280811/

有关java - onresume 后 ViewPager 中的 fragment 为空的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐