Android使用Serializable传递API数据到UniqueUnit页面崩溃如何解决
崩溃核心原因
- 从DetailedCivilization跳转到UniqueUnit时,未将Civilizations序列化对象放入Intent传递,导致UniqueUnit中读取Bundle时拿到空值,调用
getUnique_unit()触发空指针崩溃 - 存在其他潜在崩溃隐患:MainActivity中JSON解析逻辑错误、API返回的unique_unit是数组类型直接用getString读取会抛类型转换异常
修复步骤
1. 修复DetailedCivilization的数据传递逻辑
首先将Civilizations对象从局部变量改为类成员变量,跳转时带入Intent:
public class DetailedCivilization extends AppCompatActivity { public static final String TAG = "TAG"; // 新增类成员变量存储当前文明数据 private Civilizations currentCivilization; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detailed_civilization); getSupportActionBar().setTitle("Detailed view"); getSupportActionBar().setDisplayHomeAsUpEnabled(true); Intent i = getIntent(); Bundle data = i.getExtras(); // 赋值给成员变量 currentCivilization = (Civilizations) data.getSerializable("civilizationsData"); // 原有渲染逻辑不变,把之前的v替换成currentCivilization即可 TextView type = findViewById(R.id.civilizationType); type.setText(currentCivilization.getArmy_type()); TextView title = findViewById(R.id.civilizationUniqueUnits); title.setText(currentCivilization.getName()); TextView expansions = findViewById(R.id.civilizationUnitDescription); expansions.setText(currentCivilization.getExpansion()); TextView bonus = findViewById(R.id.civilizationBonus); bonus.setText(currentCivilization.getCivilization_bonus()); // 原有按钮逻辑不变 } private void activityUnit(){ Intent intent = new Intent(this, UniqueUnit.class); // 传递当前文明数据 intent.putExtra("civilizationsData", currentCivilization); startActivity(intent); } }
2. 修复MainActivity中的JSON解析错误
private void getJsonData() { String URL = "https://age-of-empires-2-api.herokuapp.com/api/v1/civilizations"; RequestQueue requestQueue = Volley.newRequestQueue(this); JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET, URL, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { JSONArray civilizations = response.getJSONArray("civilizations"); // 修正循环条件,遍历整个文明数组 for (int i=0; i< civilizations.length();i++){ JSONObject civilization = civilizations.getJSONObject(i); Civilizations v = new Civilizations(); v.setName(civilization.getString("name")); v.setArmy_type(civilization.getString("army_type")); v.setExpansion(civilization.getString("expansion")); v.setCivilization_bonus(civilization.getString("civilization_bonus")); // 修正unique_unit解析,处理数组类型 JSONArray unitArray = civilization.getJSONArray("unique_unit"); if(unitArray.length() > 0){ v.setUnique_unit(unitArray.getString(0)); }else{ v.setUnique_unit("无专属单位"); } all_civilizations.add(v); } // 循环结束后统一通知刷新,不要每次加都通知 adapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, "onErrorResponse" + error.getMessage()); } }); requestQueue.add(objectRequest); }
3. 给UniqueUnit增加空值防护,避免异常崩溃
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_unique_unit); getSupportActionBar().setTitle("Unique Unit"); getSupportActionBar().setDisplayHomeAsUpEnabled(true); Intent incomingIntent = getIntent(); // 先判断是否有传递的参数 if(incomingIntent.hasExtra("civilizationsData")){ Civilizations v = (Civilizations) incomingIntent.getSerializableExtra("civilizationsData"); if(v != null){ TextView unit = findViewById(R.id.civilizationUnitDescription); unit.setText(v.getUnique_unit()); } } }
4. 修复Adapter中ViewHolder构造方法的编译错误
public ViewHolder(@NonNull View itemView) { // 修正参数写法,View和itemView之间加空格 super(itemView); titleName = itemView.findViewById(R.id.civilizationUniqueUnits); expansionName = itemView.findViewById(R.id.civilizationUnitDescription); vv = itemView; }
内容的提问来源于stack exchange,提问作者syskeyy
相关产品推荐
相关产品推荐

