集成PayPal SDK后查看支付详情App崩溃,如何修复NullPointerException?
我在Android应用中集成了PayPal SDK,但遇到一个问题:当尝试查看支付详情时应用直接崩溃了。相关代码如下:
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; import org.json.JSONException; import org.json.JSONObject; public class PaymentDeatils extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_payment_deatils); //Getting Intent Intent intent = getIntent(); try { JSONObject jsonDetails = new JSONObject(intent.getStringExtra("PaymentDetails")); showDetails(jsonDetails.getJSONObject("response"), intent.getStringExtra("PaymentAmount")); } catch (JSONException e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } } private void showDetails(JSONObject jsonDetails, String paymentAmount) throws JSONException { //Views TextView txtId = (TextView) findViewById(R.id.txtId); TextView textViewStatus= (TextView) findViewById(R.id.txtAnount); TextView txtStatus = (TextView) findViewById(R.id.txtStatus); //Showing the details from json object txtId .setText(jsonDetails.getString("id")); textViewStatus.setText(jsonDetails.getString("state")); txtStatus.setText(paymentAmount); } }
控制台抛出的错误信息是:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
我推测问题出在JSONObject jsonDetails = new JSONObject(intent.getStringExtra("PaymentDetails"));这一行,因为intent.getStringExtra("PaymentDetails")可能为空。请问该怎么修复这个问题?
问题根源分析
你猜的没错,这个NullPointerException确实是因为intent.getStringExtra("PaymentDetails")返回了null,而JSONObject的构造函数无法接受null参数,直接触发了异常。另外我还注意到代码里有个小拼写错误:TextView textViewStatus= (TextView) findViewById(R.id.txtAnount);这里的txtAnount应该是txtAmount吧?虽然这不是崩溃的直接原因,但也建议一起修正。
修复方案
这里提供几个逐步的修复步骤,从防御性编程到根源排查:
添加空值检查,避免直接传入null给JSONObject
在创建JSONObject之前,先检查关键参数是否存在,同时给用户友好的提示:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_payment_deatils); Intent intent = getIntent(); // 先检查关键参数是否存在 String paymentDetailsStr = intent.getStringExtra("PaymentDetails"); String paymentAmountStr = intent.getStringExtra("PaymentAmount"); if (paymentDetailsStr == null || paymentAmountStr == null) { Toast.makeText(this, "支付详情数据异常,请重试", Toast.LENGTH_LONG).show(); finish(); // 直接关闭当前页面,避免后续错误 return; } try { JSONObject jsonDetails = new JSONObject(paymentDetailsStr); showDetails(jsonDetails.getJSONObject("response"), paymentAmountStr); } catch (JSONException e) { Toast.makeText(this, "解析支付详情失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); finish(); } }检查启动PaymentDeatils页面的代码,确保正确传递参数
崩溃的根本原因可能是在启动这个页面时,没有正确把PaymentDetails和PaymentAmount放入Intent中。你需要检查发起跳转的代码,比如在支付成功后的回调里,是否有类似这样的逻辑:// 示例:支付成功后跳转至PaymentDeatils页面 Intent intent = new Intent(CurrentActivity.this, PaymentDeatils.class); intent.putExtra("PaymentDetails", yourPaymentResponseJsonString); // 确保这个字符串不为空且是有效的JSON intent.putExtra("PaymentAmount", yourPaymentAmount); startActivity(intent);要确认
yourPaymentResponseJsonString确实是从PayPal SDK回调中获取的有效JSON字符串,而不是null或者空字符串。优化showDetails方法的异常处理
另外,showDetails方法里直接抛出JSONException,虽然上层有捕获,但可以考虑在方法内部做更安全的取值,比如使用optString替代getString,避免因为JSON字段缺失导致的崩溃:private void showDetails(JSONObject jsonDetails, String paymentAmount) { TextView txtId = findViewById(R.id.txtId); TextView txtAmount = findViewById(R.id.txtAmount); // 修正拼写错误 TextView txtStatus = findViewById(R.id.txtStatus); // 使用optString,字段不存在时返回默认值,避免抛出异常 txtId.setText(jsonDetails.optString("id", "未知ID")); txtAmount.setText(jsonDetails.optString("state", "未知状态")); txtStatus.setText(paymentAmount); }
额外建议
- 可以在Log中打印
paymentDetailsStr的值,确认是否为空或者格式错误,方便排查:Log.d("PaymentDebug", "PaymentDetails: " + paymentDetailsStr); - 确保PayPal SDK的回调逻辑正确,只有当支付成功且获取到完整的响应数据后,才跳转到详情页面。
内容的提问来源于stack exchange,提问作者Afams

