我使用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
并重新获取数据。
拜托,请问这附近吗?
答案 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);
}
注意:永远记住要调用超类。