0

这个问题几乎总结了它,我正在尝试保存我的片段,所以当我旋转屏幕时应用程序不会崩溃但我不确定在哪里或如何保存我的片段,我尝试使用片段管理器并将retainstate设置为true 以及检查保存的实例状态。

这是我的代码:EventsActivty - 托管片段

@Override
public void onCreate(Bundle savedInstanceState) {
    new AsyncLogin().execute(username, password);

    super.onCreate(savedInstanceState);

    username = getIntent().getStringExtra("username");
    password = getIntent().getStringExtra("password");
}

private List<Fragment> getFragments(){
    List<Fragment> fList = new ArrayList<Fragment>();

    EventListFragment eventListFragment = (EventListFragment)
         EventListFragment.instantiate(this, EventListFragment.class.getName());
    EventGridFragment eventGridFragment = (EventGridFragment) 
         EventGridFragment.instantiate(this, EventGridFragment.class.getName());

    fList.add(eventListFragment);
    fList.add(eventGridFragment);

    return fList;
}

getFragments 在这里被调用,在OnPostExecuteAsyncTask 的

    protected void onPostExecute(JSONObject jsonObject) {
        try {
            getEvents(jsonObject);
            setContentView(R.layout.eventlist);
            List<Fragment> fragments = getFragments();
            pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
            ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
            pager.setAdapter(pageAdapter);
       }

片段 1:OnCreateView

 @Override
 public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    eventObjects = ((EventsActivity)getActivity()).getEventObjects();

    setRetainInstance(true);

    View view = inflater.inflate(R.layout.eventlist ,container,false);

    final ListView listView = (ListView) view.findViewById(R.id.listView);
    listView.setAdapter(new MyCustomBaseAdapter(getActivity(), eventObjects));
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> a, View v, int position, long id) {
            Object o = listView.getItemAtPosition(position);
            EventObject fullObject = (EventObject)o;
            System.out.println("asd");
        }
    });
    return view;
}
}

片段 2:

 @Override
 public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    setRetainInstance(true);

    View view = inflater.inflate(R.layout.eventgrid ,container,false);
    GridView gridView = (GridView) view.findViewById(R.id.eventgrid);
    gridView.setAdapter(new ImageAdapter(view.getContext())); // uses the view to get the context instead of getActivity().
    return view;
}
4

2 回答 2

1

您应该了解保留片段不会阻止活动被破坏。

现在看看这里:

@Override
public void onCreate(Bundle savedInstanceState) {
     new AsyncLogin().execute(username, password);
     // ..... 
}

当屏幕方向发生变化时,您的活动仍然被破坏。结果,启动了一个新的 AsyncTask。但是当旧的 AsyncTask 完成工作时,它会尝试将结果传递给已经被销毁的旧活动。结果,这将导致崩溃。

解决方案是将 AsyncTask 放在片段本身中。这样实例就不会在方向更改时被破坏。

看看这篇文章能不能帮到你。

于 2013-08-09T07:21:41.493 回答
1

实际上, aFragmentActivity会自动恢复你在onCreate().

奇怪的是,你先打电话,然后再AsyncTask打电话.super.onCreate()Intent

即使把它放在一边,这种方法也会让你的活动在每次轮换时产生一个新的登录任务。

更好的方法是savedInstanceState检查null

if (savedInstanceState == null) {
    // first launch
    new AsyncLogin().execute(username, password);
}
...

这样它只会Activity在第一次创建时运行。

其次,您需要从您的活动中完全取消绑定登录信息。将AsyncTask您获得的任何登录结果返回Application并将其存储在那里。并且您的活动和片段从中检索该信息Application- 这样您就可以完全控制您的登录过程:您检查是否有活动会话,如果没有,您检查是否AsyncTask已经在运行,如果不是 -你需要启动它。如果是 - 你需要等待它完成(显示进度条或其他东西)。

于 2013-08-09T07:27:57.233 回答