为什么这种用于保存和恢复自定义 Arraylist 的 parcelables 实现不起作用

Why is this implementation of parcelables to save and restore Custom Arraylist not Working

我正在使用 Volley 从 json 获取数据并使用解析后的数据填充 RecyclerView 但我 运行 遇到了一些问题: 获取项目的调用在 onCreate 方法中,因此每次从配置更改和其他方式重新创建 activity 时都会重复调用;因此数据被重新加载。所以我找到了 this answer that uses parcelables 还有这个 article on Codepath(仍在 parcelables 上)。在我明确地按照说明(或者我觉得)之后,似乎没有任何变化:每次重新创建 activity 时都会重复获取数据的调用。

水果项目

public class FruitItems implements Parcelable {
    private String fruit_title;
    private String fruit_description;
    private String fruit_image;

    public String getFruit_title() {
        return fruit_title;
    }

    public void setFruit_title(String fruit_title) {
        this.fruit_title = fruit_title;
    }

    public String getFruit_description() {
        return fruit_description;
    }

    public void setFruit_description(String fruit_description) {
        this.fruit_description = fruit_description;
    }

    public String getFruit_image() {
        return fruit_image;
    }

    public void setFruit_image(String fruit_image) {
        this.fruit_image = fruit_image;
    }



    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.fruit_title);
        dest.writeString(this.fruit_description);
        dest.writeString(this.fruit_image);
    }

    public FruitItems() {
    }

    protected FruitItems(Parcel in) {
        this.fruit_title = in.readString();
        this.fruit_description = in.readString();
        this.fruit_image = in.readString();
    }

    public static final Parcelable.Creator<FruitItems> CREATOR = new Parcelable.Creator<FruitItems>() {
        @Override
        public FruitItems createFromParcel(Parcel source) {
            return new FruitItems(source);
        }

        @Override
        public FruitItems[] newArray(int size) {
            return new FruitItems[size];
        }
    };
}

主要Activity

public class MainActivity extends AppCompatActivity {

    private final String TAG = "MainActivity";
    private final String KEY_POST_ITEMS = "fruititems";

    //List of fruits
    private List<FruitItems> mFruitItemsList;

    //Views
    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private ProgressDialog mProgressDialog;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate called");

        //Initializing Views
        recyclerView = (RecyclerView) findViewById(R.id.fruit_recycler);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);



         if (savedInstanceState != null && savedInstanceState.containsKey(KEY_POST_ITEMS)) {
              mFruitItemsList = savedInstanceState.getParcelableArrayList(KEY_POST_ITEMS);

         } else {

              //Initializing the fruitlist
              mFruitItemsList = new ArrayList<>();

              if (NetworkCheck.isAvailableAndConnected(this)) {

              getData();

              } else {
            final Context mContext;
            mContext = this;
            final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
            alertDialogBuilder.setTitle(R.string.alert_titl);
            alertDialogBuilder.setCancelable(false);
            alertDialogBuilder.setIcon(R.mipmap.ic_launcher);
            alertDialogBuilder.setMessage(R.string.alert_mess);
            alertDialogBuilder.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (!NetworkCheck.isAvailableAndConnected(mContext)) {
                        alertDialogBuilder.show();
                    } else {
                        getData();
                    }

                }
            });
            alertDialogBuilder.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();

                }
            });
            alertDialogBuilder.show();


        }
          }

        adapter = new FruitAdapter(mFruitItemsList, this);

        recyclerView.setAdapter(adapter);

    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
           savedInstanceState.putParcelableArrayList(KEY_POST_ITEMS, ArrayList<? extends Parcelable>))mFruitItemsList);

           super.onSaveInstanceState(savedInstanceState);
    }


    //Getting json data

    private void getData(){
        Log.d(TAG, "getData called");
        //Show progress dialog
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setCancelable(false);
        mProgressDialog.setMessage(this.getResources().getString(R.string.load_fruit));
        mProgressDialog.show();

        //Creating a json request
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigFruit.GET_URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, "onResponse called");
                        //Dismissing the progress dialog
                        if (mProgressDialog != null) {
                            mProgressDialog.hide();
                        }


                        //calling method to parse json array
                        parseData(response);

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });

        //Creating request queue
        RequestQueue requestQueue = Volley.newRequestQueue(this);

        //Adding request to the queue
        requestQueue.add(jsonArrayRequest);

    }

    //parsing json data
    private void parseData(JSONArray array){
        Log.d(TAG, "Parsing array");


        for(int i = 0; i<array.length(); i++) {
            FruitItems fruitItem = new FruitItems();
            JSONObject jsonObject = null;
            try {
                jsonObject = array.getJSONObject(i);
                fruitItem.setFruit_title(jsonObject.getString(ConfigFruit.TAG_POST_TITLE));
                fruitItem.setFruit_description(jsonObject.getString(ConfigFruit.TAG_POST_DESCRIPTION));

                //Parsing image
                JSONObject fruitImage = jsonObject.getJSONObject("thumbnail");
                fruitItem.setFruit_image(fruitImage.getString("url"));

            } catch (JSONException w) {
                w.printStackTrace()
            }
            mFruitItemsList.add(fruitItem);
        }

        adapter.notifyItemRangeChanged(0, adapter.getItemCount());

    }

}

我可能不是专业人士,但我知道我在上面的代码中的某个地方搞砸了,否则它应该可以工作。

现在,我的问题是我哪里搞错了,我该如何弥补这个错误?

编辑

我已经编辑了上面的代码以反映我接受的答案。它工作正常,但仍然存在问题。

我从 MainActivity 开始 Activity B。如果我在 Activity B 中按下后退按钮,数据将被保存,但是当我按下向上按钮时, getData 再次被调用并且数据是重新获取。

请问这附近有没有?

您的主要活动中似乎没有 onSaveInstanceState。你需要像

这样的东西
@Override
protected void onSaveInstanceState (Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelableArrayList(KEY_POST_ITEMS,mFruitItemsList) ;
}

为了保留即将销毁的 activity 和正在创建的 activity 的数据,您需要重写 onSaveInstance 回调

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putParcelableArrayList(KEY_POST_ITEMS, (ArrayList)mFruitItemsList);

    super.onSaveInstanceState(savedInstanceState);
}

注意:永远记得调用超类。