Java.lang.NoClassDefFoundError for older versions of the Android SDK

I released a version of my application on Google Play and woke up this morning with a number of dissatisfied customers. The latest version of the app integrates support for the Bluetooth Low Energy (BTLE) heart rate monitor.

The application works fine on Android 4.3 and 4.4, but crashes in 4.0, 4.1 and 4.2 with the following error.

FATAL EXCEPTION: main java.lang.NoClassDefFoundError: com.eiref.boatcoach.MainActivity at com.eiref.boatcoach.WhatToDo.onClick(WhatToDo.java:274) at android.view.View.performClick(View.java:4204) at android.view.View$PerformClick.run(View.java:17355) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:5132) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method) 

The error occurs when creating an Intent in a simple Onclick, similar to the following ...

 public void onClick(View v) { Intent i = new Intent(this, MainActivity.class); startActivity(i); } 

After rushing and buying a 4.2 tablet, I can replicate the problem, Ive come to the conclusion that this is due to this new version of the Bluetooth LE-enabled application, which is included in the SDK 4.3 and later. If I delete all Bluetooth links in MainActivity, then the crash will disappear on 4.2 and earlier devices.

My understanding of reading the documentation was that you could write an application that includes Bluetooth LE features, and it will work on older devices only if you don't execute BTLE code using something like the following ...

 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) return; BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); mBluetoothAdapter = manager.getAdapter(); //etc. 

Therefore, my manifest.xml does not include the following, as this will prevent old devices from loading, and I obviously want to maintain a single code base ...

 <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /> 

The first question is, is my assumption higher than the ability to include BTLE code in the SDK before 4.3? If not, do I really need to create two versions of the application ... for people using 4.3 and later, and for everyone else?

There are many StackOverflow posts about java.lang.NoClassDefFoundError, and I think I read most of the relevant ones. Many people suggest that I study the Java Build Path to make sure that Android Private Libraries and Android Dependencies are checked. They are. Some suggest moving the gen folder in front of the src folder, but that doesn't seem to make any difference.

I would post an Eclipse Java Build Path image, but since this is my first post, I don't have 10 reputation points needed to insert the image, so here is another post that I followed ... Android java.lang.NoClassDefFoundError

So the second question, any other thoughts on what might be wrong in the build path?

Thank you very much in advance.


Refresh ... somehow, asking a question, I got enough points to place images of the java build path. As @Ashoke notes, I really think it has something to do with the wrong build path or with support libraries.

Eclipse order and export

Eclipse libraries

+8
android noclassdeffounderror buildpath android-bluetooth bluetooth-lowenergy
source share
4 answers

Try to get all the Ble-related code into a separate class, which you are only an instance of, if on a device with the required API levels. I think that without this, callbacks can lead to your problems.

+2
source share

I found that defining the le callback statically in activity gets an error, but including it in a function with api check will not result in the same error.

instead:

  @TargetApi(Build.VERSION_CODES.LOLLIPOP){ public class RouteMapActivity extends ActionBarActivity private BluetoothAdapter.LeScanCallback mScanCallback = new ScanCallback() {...} 

I used:

 private void setUpLeCallbacks(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); for (BTDeviceName device : mTestPointsToRead) { ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(device.le_serial).build(); filters.add(filter); } mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); } }; }else { mLeScanCallback= new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { } }; } } 
+1
source share

It is normal to get this exception on devices <4.3, because BLE does not exist, so your compiled code cannot find the corresponding classes in the OS. There is nothing wrong with your build path.

The best solution is to protect your BLE code in an if clause, to test the capabilities of BLE at run time. You should also filter the OS version in the following cases:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {...} 

You must declare android:required="false" for this function, this means that the application prefers to use this function if it is present on the device, but if necessary it works without the specified function.

 <uses-feature android:name="android.hardware.bluetooth_le" android:required="false" /> 
0
source share

Now that you are using APIs that may not be available in older versions of Android, make sure you package the application with the appropriate support library.

For example, see this BluetoothLeGattSample android sample . It uses below lib support.

  dependencies { // Add the support lib that is appropriate for SDK 18 compile "com.android.support:support-v13:19.0.+" } 

see android docs for eclipse instructions for setting up support library

0
source share

All Articles