1

I use Google Maps in a project and build it with Android.mk. But still (after days of research) cann't figure out how to solve NoClassDefFoundError which crashes the apk in time Google Maps fragment inflation is happen. Can any inside me about a way it have to be solved? Detalization is below.

Google Play Services library is added in the following way:

#Adding classpath to Google Play Services classes
LOCAL_CLASSPATH += $(LOCAL_PATH)/google-play-services_lib/bin/
...
#Google Play Services
LOCAL_STATIC_JAVA_LIBRARIES += google-play-services \
                                google-play-services_lib
...
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += google-play-services:libs/google-play-services.jar \
                                        google-play-services_lib:libs/google-play-services_lib.jar

Build goes fine but application throws runtime error when tries to inflate layout with Google Maps fragment. LogCat:

**java.lang.NoClassDefFoundError**:
java.lang.NoClassDefFoundError: com.google.android.gms.R$styleable
    at com.google.android.gms.maps.GoogleMapOptions.createFromAttributes(Unknown Source)
    at com.google.android.gms.maps.MapFragment.onInflate(Unknown Source)
    at android.app.Activity.onCreateView(Activity.java:4996)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
    at com.mapsvisitor.ui.MapsFragment.onCreateView(MapsFragment.java:81)
    ...

Code:

final View layout = inflater.inflate(R.layout.maps_layout, null);

Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map_main"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:orientation="vertical">
        <fragment
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.MapFragment" />
</LinearLayout>
Yehor Nemov
  • 907
  • 2
  • 16
  • 31
  • 1
    Looks like you haven't referenced google play services properly – Raghunandan Jul 09 '14 at 08:52
  • It looks so. But Google Play Services utils returns **True** for `isGooglePlayServicesAvailable` query. Have you any ideas how to references it within makefile? – Yehor Nemov Jul 09 '14 at 08:58
  • Can you check properly if you have referenced google play services. Your device might have google play servicesa apk installed but have you referenced the same in your project?? – Raghunandan Jul 09 '14 at 09:01
  • Google play services version is correct (4452000). It's registered in manifest ``. The problem with outdated services is happen before when `isGooglePlayServicesAvailable` has returned `ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED` (I have solved it earlier here: [How to update Google Play Services through adb?](http://stackoverflow.com/questions/24606574/how-to-update-google-play-services-through-adb)). – Yehor Nemov Jul 09 '14 at 09:41
  • that is the only reason i can think of as of now – Raghunandan Jul 09 '14 at 09:45

1 Answers1

1

The problem is in that when you use dependency project as a library the generated JAR (google-play-services_lib.jar) is not suitable for independent use (as java static libraries). As solution simple use JAR generated by Eclipse export instead in the following way Export > Java > JAR file with selected src and gen folders to export: enter image description here

The following snippet helps to define that com.google.android.gms.R and nested classes are unavailable (com.google.android.gms.R$attr, com.google.android.gms.R$color, etc):

void isClassesAvailable(List<String> classes) {
    for(String cl: classes) {
        try {
            Class.forName(cl);
        }
            catch (ClassNotFoundException e) {
            Log.w(TAG, e.getMessage());
        }
    }
}

How JAR is packed for dependency project (with src folder classes. See folder "android" below): enter image description here

How JAR has to be packed for robust static library (with src and gen folder classes. See folders "android" and "com" below): enter image description here

However before idiomatically right solution which uses Eclipse export light hack becomes the GTD. Simple repacking google-play-services_lib.jar with google-play-services_lib/bin/classes content and previously presented there ones makes all resource's classes available.

Yehor Nemov
  • 907
  • 2
  • 16
  • 31