Android LoaderCallbacks.onLoadFinished()从未使用FragmentPager调用过吗?

Android LoaderCallbacks.onLoadFinished()从未使用FragmentPager调用过吗?,android,Android,我正在使用FragmentPagerAdapter实现一个选项卡式界面。我的第0个片段在创建时创建加载程序,并尝试在onActivityCreated()中重新连接到加载程序。下面是课程: public class My0thFragment extends Fragment { private boolean ranOnce = false; @Override public void onCreate(Bundle savedInstanceState) {

我正在使用FragmentPagerAdapter实现一个选项卡式界面。我的第0个片段在创建时创建加载程序,并尝试在onActivityCreated()中重新连接到加载程序。下面是课程:

public class My0thFragment extends Fragment {
    private boolean ranOnce = false;

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

    @Override
    public void onActivityCreated() {
        if (!ranOnce) {
            // if the first time we're being created, do an initial load of data.
            getLoaderManager().initLoader(500, null, mMyCallback).forceLoad();
            ranOnce = true;
        } else {
            // reconnect?
            getLoaderManager().initLoader(500, null, mMyCallback);

            // sanity check.
            printAllLoaders(getLoaderManager());
        }
    }

    private LoaderManager.LoaderCallbacks<Foo> mMyCallback = new LoaderManager.LoaderCallbacks<Foo>() {
        @Override
        public Loader<Foo> onCreateLoader(int arg0, Bundle arg1) {
            return new FooLoader(getActivity(), arg1);
        }

        @Override
        public void onLoadFinished(Loader<Foo> arg0, Foo arg1) {
            Log.e(tag, "onLoadFinished()!");
        }

        @Override
        public void onLoaderReset(Loader<Foo> arg0) {
            Log.e(tag, "onLoaderReset()!");
        }
    };
}
公共类My0thFragment扩展了片段{
私有布尔值ranOnce=false;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(真);
}
@凌驾
ActivityCreated()上的公共无效{
如果(!ranOnce){
//如果我们是第一次被创建的,请进行初始数据加载。
getLoaderManager().initLoader(500,null,mMyCallback).forceLoad();
ranOnce=真;
}否则{
//重新连接?
getLoaderManager().initLoader(500,null,mMyCallback);
//精神检查。
printAllLoaders(getLoaderManager());
}
}
私有LoaderManager.LoaderCallbacks mMyCallback=新LoaderManager.LoaderCallbacks(){
@凌驾
公共加载器onCreateLoader(int arg0,Bundle arg1){
返回新的傻瓜加载程序(getActivity(),arg1);
}
@凌驾
public void onLoadFinished(加载程序arg0、Foo arg1){
Log.e(标记“onLoadFinished()!”);
}
@凌驾
公共void onLoaderReset(加载程序arg0){
Log.e(标记“onLoaderReset()!”);
}
};
}
下面是一个场景:

  • 应用程序启动时,在FragmentPagerAdapter中创建第0个片段
  • 调用onActivityCreated()方法,该方法在第一次运行时创建并启动加载程序
  • 在加载程序完成之前,我快速切换到另一个选项卡
  • 我可以查看加载程序完成的日志,但是我的回调永远不会得到onLoadFinished()回调。我假设这是因为片段处于某种分离状态,这取决于FragmentPagerAdapter的工作方式
  • 返回第0个选项卡,我看到onActivityCreated()被调用,initLoader()方法再次被调用。回拨仍然没有启动
  • 此时,我可以在加载程序管理器中打印所有加载程序,并看到我的加载程序仍然位于加载程序管理器中
  • 所以我被困在这里,我一定是做错了什么,因为加载程序的设计一定是为了让我们的开发人员在考虑片段生命周期的情况下轻松使用。有人能指出我做错了什么吗

    谢谢

    请参阅API演示或Support4Demos中的示例代码文件。它提供了一个ViewPager和一个TabHost来控制同一组片段。我破解了它以完全覆盖你描述的案例。(您是否直接与我联系了?)需要注意的主要问题是,示例应用程序没有分离ViewPager中的片段

    这是我破解的部分:

        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();
    
        mViewPager = (ViewPager)findViewById(R.id.pager);
    
        mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
    
        mTabsAdapter.addTab(mTabHost.newTabSpec("fraga").setIndicator("Fragment A"),
                FragmentA.class, null);
        mTabsAdapter.addTab(mTabHost.newTabSpec("fragb").setIndicator("Fragment B"),
                FragmentB.class, null);
    
        if (savedInstanceState != null) {
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
        }
    
    }
    
    片段A包含加载程序。

    请参阅API演示或Support4Demos中的示例代码文件。它提供了一个ViewPager和一个TabHost来控制同一组片段。我破解了它以完全覆盖你描述的案例。(您是否直接与我联系了?)需要注意的主要问题是,示例应用程序没有分离ViewPager中的片段

    这是我破解的部分:

        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();
    
        mViewPager = (ViewPager)findViewById(R.id.pager);
    
        mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
    
        mTabsAdapter.addTab(mTabHost.newTabSpec("fraga").setIndicator("Fragment A"),
                FragmentA.class, null);
        mTabsAdapter.addTab(mTabHost.newTabSpec("fragb").setIndicator("Fragment B"),
                FragmentB.class, null);
    
        if (savedInstanceState != null) {
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
        }
    
    }
    

    片段A是包含加载程序的片段。

    不知道您是否解决了问题,但您应该在Fragment.onStart()上调用forceLoad(),而不是Fragment.onActivityCreated()


    myCallback.onLoadFinished()永远不会被调用,因为在片段启动之前,“myCallback”实际上不会附加到加载程序。

    不知道问题是否已解决,但应该在fragment.onStart()上调用forceLoad(),而不是fragment.onActivityCreated()


    myCallback.onLoadFinished()永远不会被调用,因为在片段启动之前,“myCallback”实际上不会附加到加载程序。

    可能您有两个相同片段的实例,请尝试在销毁片段上销毁加载程序:

    protected void onDestroy() {
       if (getSupportLoaderManager().getLoader(0) != null) {
                getLoaderManager().getLoader(0).abandon();
                getSupportLoaderManager().destroyLoader(0);
        }
        super.onDestroy();
    }
    

    可能您有两个相同片段的实例,请在销毁片段上尝试销毁加载程序:

    protected void onDestroy() {
       if (getSupportLoaderManager().getLoader(0) != null) {
                getLoaderManager().getLoader(0).abandon();
                getSupportLoaderManager().destroyLoader(0);
        }
        super.onDestroy();
    }