Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ViewPager和Activity在Activity onDestroy onCreate之后以片段形式重新创建/持久化数据_Android_Android Fragments_Android Viewpager - Fatal编程技术网

Android ViewPager和Activity在Activity onDestroy onCreate之后以片段形式重新创建/持久化数据

Android ViewPager和Activity在Activity onDestroy onCreate之后以片段形式重新创建/持久化数据,android,android-fragments,android-viewpager,Android,Android Fragments,Android Viewpager,我用ViewPager编写了一个活动,它在执行AsyncTask后填充。每个TestDataObject都绑定到相关的TestFragment。当屏幕旋转时,由于NullPointerException内部onCreateView方法,应用程序会崩溃。我相信这是因为ViewPager/AdapteronSaveInstanceState方法,onCreateView在数据还不可用时尝试在AsyncTask数据加载之前恢复数据 如果onCreateView代码,我就可以,但我觉得这不是一个正确的解

我用
ViewPager
编写了一个活动,它在执行
AsyncTask
后填充。每个
TestDataObject
都绑定到相关的
TestFragment
。当屏幕旋转时,由于
NullPointerException
内部
onCreateView
方法,应用程序会崩溃。我相信这是因为
ViewPager
/Adapter
onSaveInstanceState
方法,
onCreateView
在数据还不可用时尝试在
AsyncTask
数据加载之前恢复数据

如果onCreateView代码,我就可以
,但我觉得这不是一个正确的解决方案,因为ViewPager中的片段数量可能会有所不同,因此它可能会做一些不必要的工作:恢复更改后的ViewPager内容,然后替换为初始内容。在这种情况下,onSaveInstanceState似乎过于有害。大概,我可以扩展ViewPager或Adapter来取消保存过程——我也觉得这很奇怪

你有更好的建议吗

public class MainActivity extends LoggerActivity {

    private ArrayList<TestDataObject> mDataObjects = new ArrayList<MainActivity.TestDataObject>();

    private ViewPager mViewPager;
    private TestFragmentAdapter mViewPagerAdapter;

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

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPagerAdapter = new TestFragmentAdapter(
                getSupportFragmentManager(), mDataObjects);
        mViewPager.setAdapter(mViewPagerAdapter);
        new TestAsyncTask().execute();
    }

    private class TestAsyncTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            mDataObjects.add(new TestDataObject());
            mDataObjects.add(new TestDataObject());
            mDataObjects.add(new TestDataObject());
            mViewPagerAdapter.notifyDataSetChanged();

        }
    }

    public static class TestFragment extends Fragment {

        private TestDataObject mDataObject;

        public static TestFragment getInstance(TestDataObject obj) {
            TestFragment f = new TestFragment();
            f.mDataObject = obj;
            return f;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            // layout.find...
            mDataObject.toString();
            return inflater.inflate(R.layout.fragment_test, null, false);
        }

    }

    public static class TestFragmentAdapter extends FragmentStatePagerAdapter {

        private List<TestDataObject> mDataObjects;

        public TestFragmentAdapter(FragmentManager fm, List<TestDataObject> objs) {
            super(fm);
            mDataObjects = objs;
        }

        @Override
        public Fragment getItem(int position) {
            return TestFragment.getInstance(mDataObjects.get(position));
        }

        @Override
        public int getCount() {
            return mDataObjects == null ? 0 : mDataObjects.size();
        }

    }

    public static class TestDataObject {
    }
}
public类MainActivity扩展了LoggerActivity{
private ArrayList mDataObjects=new ArrayList();
私有视图寻呼机mViewPager;
私有TestFragmentAdapter mViewPagerAdapter;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager=(ViewPager)findViewById(R.id.pager);
mViewPagerAdapter=新的TestFragmentAdapter(
getSupportFragmentManager(),mDataObjects);
setAdapter(mViewPagerAdapter);
new TestAsyncTask().execute();
}
私有类TestAsyncTask扩展了AsyncTask{
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
时间单位。秒。睡眠(3);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(void结果){
super.onPostExecute(结果);
添加(新的TestDataObject());
添加(新的TestDataObject());
添加(新的TestDataObject());
mViewPagerAdapter.notifyDataSetChanged();
}
}
公共静态类TestFragment扩展了片段{
私有TestDataObject-mDataObject;
公共静态TestFragment getInstance(TestDataObject obj){
TestFragment f=新的TestFragment();
f、 mDataObject=obj;
返回f;
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
//布局。查找。。。
mDataObject.toString();
返回充气机。充气(R.layout.fragment_测试,空,假);
}
}
公共静态类TestFragmentAdapter扩展了FragmentStatePagerAdapter{
私有列表对象;
公共TestFragmentAdapter(FragmentManager fm,列表objs){
超级(fm);
mDataObjects=objs;
}
@凌驾
公共片段getItem(int位置){
返回TestFragment.getInstance(mDataObjects.get(position));
}
@凌驾
public int getCount(){
返回mDataObjects==null?0:mDataObjects.size();
}
}
公共静态类TestDataObject{
}
}
我相信这是因为SaveInstanceState上的ViewPager/适配器 方法。onCreateView尝试在异步任务之前还原数据 数据尚未可用时加载数据

事实并非如此(我假设您在
mDataObject.toString();
处获得异常),即使
AsyncTask
会立即完成其工作,也会引发异常。第一次运行应用程序后,
ViewPager
将包含三个片段。当您打开手机时,
活动
将被销毁并重新创建。
ViewPager
将尝试重新创建其中的片段,但这次它将使用默认的空构造函数(这就是为什么不应该使用非空构造函数传递数据)。如您所见,适配器第一次创建
片段
时,它将由
getInstance
方法创建(这也是初始化
mDataObject
的唯一点),您将
TestDataObject
对象传递到该方法。当
ViewPager
重新初始化其片段时,该字段也将初始化

如果可以将
TestDataObject
放入
Bundle
中,那么您可以简单地调整
getInstance
方法,将一些参数传递给片段(因此当
ViewPager
重新创建它们时,数据字段将被初始化)。我相信你已经看到:

public static TestFragment getInstance(TestDataObject obj) {
      TestFragment f = new TestFragment();
      // f.mDataObject = obj; <- don't do this
      // if possible
      Bundle args = new Bundle();
      args.put("data", obj); // only if obj can be put in a Bundle
      f.setArguments(args); 
      return f;
}

private TestDataObject mDataObject; 

@Override
public void onCreate(Bundle savedInstance) {
     mDataObject = getArguments().get("data"); // again, depends on your TestDataObject 
}
publicstatictestfragmentgetinstance(testdataobjectobj){
TestFragment f=新的TestFragment();

//f.mDataObject=obj;我想您需要添加理解代码所需的部分代码,例如onSavedInstance方法。我对onSaveInstanceState没有任何处理。是组件本身试图保存当前视图状态。我可能应该研究有不同的方法来持久化状态(旋转只是需要保持状态的一个示例)。一种方法是实现onSaveInstanceState并在以后检索数据。另一种方法只是你的链接建议的方式,不如实现你自己的onSaveInstanceState灵活。如果我没记错,如果你使用这种方法,应用程序不会根据当前的新方向查找新布局,你应该这样做你的