java.lang.NoClassDefFoundError: java.util.Objects
java.lang.NoClassDefFoundError: java.util.Objects
我在 Android 开发控制台中收到以下崩溃报告。
我的应用程序 运行 在我试用该应用程序的模拟器或设备上运行良好,但出于某种原因在 Galaxy Nexus (Maguro) 上它没有 运行。我也没有遇到任何编译错误。
java.lang.NoClassDefFoundError: java.util.Objects
at com.nivelsonic.nivelsonic.MyTankActivity.onResponse(MyTankActivity.java:199)
at com.nivelsonic.nivelsonic.MyTankActivity.onResponse(MyTankActivity.java:160)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
MyTankActivity.java
public void drawTankStatus() {
tankView = (TankView) this.findViewById(R.id.vMyTank);
tvLocation = (TextView) this.findViewById(R.id.tvLocation);
tvLevel = (TextView) this.findViewById(R.id.tvLevel);
ivRssi = (ImageView) this.findViewById(R.id.ivRssi);
ivSettings = (ImageView) this.findViewById(R.id.ivSettings);
ivAlert = (ImageView) this.findViewById(R.id.ivAlert);
final Response.Listener<String> responseListener = new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
//int success = jsonResponse.getInt("success");
JSONArray tank_data = jsonResponse.getJSONArray("tank_data");
if (tank_data.length() > 0) {
int i;
for (i = 0; i < tank_data.length(); i++) {
//Log.v("Result--", "" + tank_data.getString(i));
JSONObject tankObj = tank_data.getJSONObject(0);
location = (String) tankObj.getString("Location");
color = (String) tankObj.getString("Color");
level = (int) tankObj.getInt("CurrentLevel");
rssi = (int) tankObj.getInt("RSSI");
phone = (String) tankObj.getString("Phone");
status = (int) tankObj.getInt("Status");
Integer numOfNotifications = tankObj.getInt("NumberOfNotifications");
if (numOfNotifications > 0) {
ivAlert.setImageResource(R.drawable.alert_red);
} else {
ivAlert.setImageResource(R.drawable.alert);
}
tvLocation.setText(location);
if (level <= 55) {
tvLevel.setTextColor(Color.parseColor("#064e7b"));
} else {
// colo rvariable gets set from a value calculated in A_get_tanks.php
if (Objects.equals("#FFFFAD", color)) {
tvLevel.setTextColor(Color.parseColor("#064e7b"));
} else {
tvLevel.setTextColor(Color.parseColor("#FFFFFF"));
}
}
String levelPercent = Integer.toString(level);
tvLevel.setText(levelPercent + "%");
if (status != 0) {
switch (rssi) {
case 0:
ivRssi.setImageResource(R.drawable.rssi0);
break;
case 1:
ivRssi.setImageResource(R.drawable.rssi1);
break;
case 2:
ivRssi.setImageResource(R.drawable.rssi2);
break;
case 3:
ivRssi.setImageResource(R.drawable.rssi3);
break;
case 4:
ivRssi.setImageResource(R.drawable.rssi4);
break;
case 5:
ivRssi.setImageResource(R.drawable.rssi5);
break;
}
} else {
ivRssi.setImageResource(R.drawable.disconnected);
}
tankView.drawLevel(level, color);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Intent intent = getIntent();
userid = intent.getStringExtra("userid");
impid = intent.getStringExtra("impid");
MyTankRequest myTankRequest = new MyTankRequest(userid, responseListener);
RequestQueue queue = Volley.newRequestQueue(MyTankActivity.this);
queue.add(myTankRequest);
if (ivSettings != null) {
ivSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent settingsIntent = new Intent(MyTankActivity.this, SettingsActivity.class);
settingsIntent.putExtra("impid", impid);
MyTankActivity.this.startActivity(settingsIntent);
}
});
}
}
抛出异常是因为java.util.Objects
的所有静态方法在API19(Android4.4.+).
以上都可用
正如您在评论中所说,您的设备具有 API 10 (Android 2.3.+),因此 Android 版本和 NoClassDefFoundError
被抛出。
如果您想以编程方式检查 api 级别,您可以执行以下操作:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// your code available only above api 19
} else {
// compatibility code
}
在我的例子中,升级到 Retrofit
2.7.1 后,此异常发生在 Android 4。
见 https://github.com/square/retrofit/blob/master/CHANGELOG.md:
Version 2.7.0 (2019-12-09)
This release changes the minimum requirements to Java 8+ or Android
5+. See this blog post for more information on the change.
New: Upgrade to OkHttp 3.14.4. Please see its changelog for 3.x.
另见 https://github.com/square/retrofit/issues/3201 and https://github.com/square/retrofit/issues/3042。
Retrofit
取决于 OkHttp
在 version 3.13.
中拒绝 API 21 之前的支持
因此,将 Retrofit
降级到 2.6.4 甚至 2.6.0 之前。我检查了,它解决了问题。同时将 Retrofit Gson 转换器 (com.squareup.retrofit2:converter-gson) 降级到 2.6.4.
我在 Android 开发控制台中收到以下崩溃报告。 我的应用程序 运行 在我试用该应用程序的模拟器或设备上运行良好,但出于某种原因在 Galaxy Nexus (Maguro) 上它没有 运行。我也没有遇到任何编译错误。
java.lang.NoClassDefFoundError: java.util.Objects
at com.nivelsonic.nivelsonic.MyTankActivity.onResponse(MyTankActivity.java:199)
at com.nivelsonic.nivelsonic.MyTankActivity.onResponse(MyTankActivity.java:160)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
MyTankActivity.java
public void drawTankStatus() {
tankView = (TankView) this.findViewById(R.id.vMyTank);
tvLocation = (TextView) this.findViewById(R.id.tvLocation);
tvLevel = (TextView) this.findViewById(R.id.tvLevel);
ivRssi = (ImageView) this.findViewById(R.id.ivRssi);
ivSettings = (ImageView) this.findViewById(R.id.ivSettings);
ivAlert = (ImageView) this.findViewById(R.id.ivAlert);
final Response.Listener<String> responseListener = new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
//int success = jsonResponse.getInt("success");
JSONArray tank_data = jsonResponse.getJSONArray("tank_data");
if (tank_data.length() > 0) {
int i;
for (i = 0; i < tank_data.length(); i++) {
//Log.v("Result--", "" + tank_data.getString(i));
JSONObject tankObj = tank_data.getJSONObject(0);
location = (String) tankObj.getString("Location");
color = (String) tankObj.getString("Color");
level = (int) tankObj.getInt("CurrentLevel");
rssi = (int) tankObj.getInt("RSSI");
phone = (String) tankObj.getString("Phone");
status = (int) tankObj.getInt("Status");
Integer numOfNotifications = tankObj.getInt("NumberOfNotifications");
if (numOfNotifications > 0) {
ivAlert.setImageResource(R.drawable.alert_red);
} else {
ivAlert.setImageResource(R.drawable.alert);
}
tvLocation.setText(location);
if (level <= 55) {
tvLevel.setTextColor(Color.parseColor("#064e7b"));
} else {
// colo rvariable gets set from a value calculated in A_get_tanks.php
if (Objects.equals("#FFFFAD", color)) {
tvLevel.setTextColor(Color.parseColor("#064e7b"));
} else {
tvLevel.setTextColor(Color.parseColor("#FFFFFF"));
}
}
String levelPercent = Integer.toString(level);
tvLevel.setText(levelPercent + "%");
if (status != 0) {
switch (rssi) {
case 0:
ivRssi.setImageResource(R.drawable.rssi0);
break;
case 1:
ivRssi.setImageResource(R.drawable.rssi1);
break;
case 2:
ivRssi.setImageResource(R.drawable.rssi2);
break;
case 3:
ivRssi.setImageResource(R.drawable.rssi3);
break;
case 4:
ivRssi.setImageResource(R.drawable.rssi4);
break;
case 5:
ivRssi.setImageResource(R.drawable.rssi5);
break;
}
} else {
ivRssi.setImageResource(R.drawable.disconnected);
}
tankView.drawLevel(level, color);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Intent intent = getIntent();
userid = intent.getStringExtra("userid");
impid = intent.getStringExtra("impid");
MyTankRequest myTankRequest = new MyTankRequest(userid, responseListener);
RequestQueue queue = Volley.newRequestQueue(MyTankActivity.this);
queue.add(myTankRequest);
if (ivSettings != null) {
ivSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent settingsIntent = new Intent(MyTankActivity.this, SettingsActivity.class);
settingsIntent.putExtra("impid", impid);
MyTankActivity.this.startActivity(settingsIntent);
}
});
}
}
抛出异常是因为java.util.Objects
的所有静态方法在API19(Android4.4.+).
正如您在评论中所说,您的设备具有 API 10 (Android 2.3.+),因此 Android 版本和 NoClassDefFoundError
被抛出。
如果您想以编程方式检查 api 级别,您可以执行以下操作:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// your code available only above api 19
} else {
// compatibility code
}
在我的例子中,升级到 Retrofit
2.7.1 后,此异常发生在 Android 4。
见 https://github.com/square/retrofit/blob/master/CHANGELOG.md:
Version 2.7.0 (2019-12-09)
This release changes the minimum requirements to Java 8+ or Android 5+. See this blog post for more information on the change.
New: Upgrade to OkHttp 3.14.4. Please see its changelog for 3.x.
另见 https://github.com/square/retrofit/issues/3201 and https://github.com/square/retrofit/issues/3042。
Retrofit
取决于 OkHttp
在 version 3.13.
因此,将 Retrofit
降级到 2.6.4 甚至 2.6.0 之前。我检查了,它解决了问题。同时将 Retrofit Gson 转换器 (com.squareup.retrofit2:converter-gson) 降级到 2.6.4.