为什么这个parcelables实现保存和恢复自定义Arraylist不工作

时间:2016-04-15 21:18:58

标签: android android-recyclerview parcelable

我使用Volley从json获取数据并使用已解析的数据填充RecyclerView但我遇到了一些问题: 获取项目的调用采用onCreate方法,因此每次从配置更改和其他方面重新创建活动时都会重复调用;因此重新加载数据。所以我找到了this answer that uses parcelables 而这article on Codepath(仍然是在parcelables)。在我明确地遵循了指令之后(或者我觉得),似乎没有变化:每次重新创建活动时都会重复调用获取数据。

FruitItems

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];
        }
    };
}

MainActivity

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 开始活动B 。如果我按活动B 中的后退按钮,数据会被保存,但是当我按下向上按钮时,会再次调用getData并重新获取数据。

拜托,请问这附近吗?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

为了保留您即将被销毁的活动和正在创建的活动的数据,您需要覆盖onSaveInstance回调

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

    super.onSaveInstanceState(savedInstanceState);
}

注意:永远记住要调用超类。