如何使用onSaveInstanceState保存和恢复片段上的接口

时间:2015-05-25 15:12:32

标签: android fragment parcelable serializable

当我的片段重新加载时,我需要恢复变量。除了我的回调之外,所有其他变量都在工作。

我有一个像这样的片段:

公共类ClosetFragment扩展Fragment {

private String [] closetSessions = null;
private DBName dbName = null;
private String token = null;
private RefreshCallback callback= null;

public ClosetFragment(String [] closetSessions, DBName dbName, String token, RefreshCallback callback){
    this.closetSessions = closetSessions;
    this.dbName = dbName;
    this.token = token;
    this.callback = callback;

}
public ClosetFragment(){

}

  @Override
    public void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable("closetSessions", (Serializable) this.closetSessions);
        outState.putSerializable("dbName", (Serializable) this.dbName);
        outState.putSerializable("token", (Serializable) this.token);
        outState.putSerializable("callback", (Serializable) this.callback);
    }

我的回调是:

public interface RefreshCallback extends Serializable{
     public void onNeedrefresh();
}

我得到的例外是:

AppSectionsPagerAdapter是实现我的回调的类。

05-25 12:04:06.037: E/AndroidRuntime(10822): FATAL EXCEPTION: main
05-25 12:04:06.037: E/AndroidRuntime(10822): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = br.com.closet4share.app.adapters.AppSectionsPagerAdapter$1)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeSerializable(Parcel.java:1279)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeValue(Parcel.java:1233)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeMapInternal(Parcel.java:591)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Bundle.writeToParcel(Bundle.java:1627)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeBundle(Parcel.java:605)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:135)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeTypedArray(Parcel.java:1102)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:378)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeParcelable(Parcel.java:1254)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeValue(Parcel.java:1173)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeMapInternal(Parcel.java:591)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Bundle.writeToParcel(Bundle.java:1627)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.os.Parcel.writeBundle(Parcel.java:605)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2535)
05-25 12:04:06.037: E/AndroidRuntime(10822):    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3151)

非常感谢您的帮助!

这是我实现回调的方式:

@Override
    public Fragment getItem(int i) {

        Fragment fragment = null;

        fragment = new ClosetFragment(i,closetSessions,dbName,token, new RefreshCallback(){

            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public void onNeedrefresh() {
                AppSectionsPagerAdapter.this.notifyDataSetChanged();

            }

        });
        mPageReferences.put(i, new WeakReference<Fragment>(fragment));

        return fragment;

    }

3 个答案:

答案 0 :(得分:1)

发生异常是因为匿名内部类包含父适配器的成员变量 - 这是您通过AppSectionsPagerAdapter.this访问的,而适配器不是可序列化的。

你不能以这种方式坚持回调,说实话,你甚至不应该尝试这样做。仅保留片段的内部数据,并在getItem中单独设置回调。

答案 1 :(得分:1)

在我的活动中,我创建了方法:

public void refreshAdapter(){
        if (mAppSectionsPagerAdapter != null)
            mAppSectionsPagerAdapter.notifyDataSetChanged();
    }

并在我的片段中打电话:

Closet closet = (Closet)getActivity();
            closet.refreshAdapter();

并且没有任何保存。谢谢@vzsg。

答案 2 :(得分:0)

public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {

    private ArrayList<String> todoItems;
    private ArrayAdapter<String> adapter;

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

        if(savedInstanceState == null) {
            todoItems = new ArrayList<String>();
        } else {
            todoItems = savedInstanceState.getStringArrayList("todoItemTag");//the tag must match what the variable was saved with
        }

        FragmentManager fm = getFragmentManager();

        ToDoListFragment listToDo = new ToDoListFragment();
        listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
        listToDo.setListAdapter(adapter);
    }

    public void OnToDoAdded(String newToDo) {
        todoItems.add(newToDo);
        adapter.notifyDataSetChanged();

    }

    @Override
    protected void onSavedInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        oustate.putStringArrayList("todoItemTag", todoItems);//it would be advised to make the tags a static final String
    }
}

您需要覆盖onSavedInstanceState方法,以便了解何时需要保存状态。然后,您还需要更新onCreate方法以检查savedInstanceState是否为null。如果为null,则表示尚未启动活动。这是MainActivity类的示例,您可以从那里开始: