15

So I'm developing a cheesy app to make posts to train myself in android before I work on my firm's real app project. I'm running into a bug that's giving me a very difficult time though.

I was given a list of library dependencies that I was to use, and have my build.gradle file set up to load them in. It syncs fine, so I assume it's done right to the best of my knowledge:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.google.android.gms:play-services:7.3.0'
    compile 'com.squareup.okhttp:okhttp:2.3.0'
    compile 'com.squareup.retrofit:retrofit:1.7.0'
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.squareup.dagger:dagger:1.2.2'
    compile 'com.squareup.dagger:dagger-compiler:1.2.2'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.android.support:recyclerview-v7:22.1.1'
    compile 'com.squareup:otto:1.3.7'
    compile 'com.path:android-priority-jobqueue:1.1.2'
    compile 'io.realm:realm-android:0.80.1'
    compile 'com.jakewharton:butterknife:6.1.0'
    compile 'com.android.support:multidex:1.0.0'
    compile 'com.android.support:appcompat-v7:22.1.1'
}

And I have actually installed the android support library AND repository: SDK Manager Proof I've installed what I need

And yet I still try and launch the app and get the following stack trace:

java.lang.NoClassDefFoundError: android.support.v7.appcompat.R$attr
        at android.support.v7.app.AppCompatDelegateImplV7.ensureSubDecor(AppCompatDelegateImplV7.java:286)
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:246)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
        at com.anglersatalas.twitstagram.MainActivity.onCreate(MainActivity.java:23)
        at android.app.Activity.performCreate(Activity.java:5451)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
        at android.app.ActivityThread.access$900(ActivityThread.java:169)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:146)
        at android.app.ActivityThread.main(ActivityThread.java:5487)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
        at dalvik.system.NativeStart.main(Native Method)

Everywhere else on Stack Overflow I've seen has the solution as adding the appcompat v7 libraries as they say to do on the android website, which I've demonstrated I've done above. I can't figure out for the life of me why this is still happening. Looking at the stack trace, it breaks in my MainActivity at the setContentView() method:

package com.anglersatalas.twitstagram;

import android.os.Bundle;
import com.anglersatalas.twitstagram.R;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

import com.anglersatalas.twitstagram.api.PostService;
import com.anglersatalas.twitstagram.models.Post;

import java.util.List;

import retrofit.RestAdapter;


public class MainActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(com.anglersatalas.twitstagram.R.layout.activity_main);

        TextView tv =  (TextView)findViewById(com.anglersatalas.twitstagram.R.id.textView);

        RestAdapter adapter = new RestAdapter.Builder()
                .setEndpoint("10.0.0.248/testserver/backend/web")
                .build();

        PostService service = adapter.create(PostService.class);
        List<Post> list = service.getPosts();
        String str = "";
        for(Post p : list){
            str += String.format("%s\n", p);
        }
        tv.setText(str);

    }

    ...

}

Clicking through to the class file that is calling the method that throws the exception, it shows that it can't find 'android.support.v7.appcompat.R;':

enter image description here

My coworkers and I are at a loss. Any suggestions as to how to remedy this?

MrFlick
  • 195,160
  • 17
  • 277
  • 295
cbhedd
  • 289
  • 4
  • 10
  • It's a generated file. I would suggest a `Build > Clean`. – tachyonflux May 13 '15 at 20:52
  • I've done that as well. It doesn't seem to have any effect because it's an imported library's R file that is 'missing', not mine. I put missing in quotes because I can literally see it in the project sidebar. – cbhedd May 13 '15 at 21:00
  • Delete that R file then try [Invalidate Cache and Restart IDE] – Eenvincible May 13 '15 at 21:25
  • Not sure about that error, but I see another error you will get once that is resolved. You have `compile 'com.google.android.gms:play-services:7.3.0'` but you don't have Google Play Services installed. – Daniel Nugent May 13 '15 at 21:36

2 Answers2

50

I just spent hours with this same issue, and I was able to get it resolved...

It turns out I was over the dex limit, I did have multiDexEnabled true in my build.gradle file under defaultConfig, but it looks like I was missing a few other things for pre 5.0 devices..

defaultConfig { 
...
        multiDexEnabled true 
... }

I first checked my method count with this: https://github.com/mihaip/dex-method-counts

I was at 67952 methods...

I then updated my build.gradle to add multidex support

dependencies {
...
compile 'com.android.support:multidex:1.0.0'
... }

I then updated my Application (we already have our own) to extend from MultiDexApplication

package com.me.myapp
...
public class Application extends MultiDexApplication {}

Here were the two links from the documentation I used to correctly implement multidex: https://developer.android.com/tools/building/multidex.html https://developer.android.com/reference/android/support/multidex/MultiDexApplication.html

Make sure your application in the manifest points to your custom multidex application

<application
...
android:name="com.me.myapp.Application" />
Chrispix
  • 17,941
  • 20
  • 62
  • 70
  • 1
    This looks super promising! I will end up in a place where I'll have to add multidex support, but in the meantime since I wasn't getting anywhere I restarted from scratch, and have had no issues since. Thanks for the answer! Should I mark it as correct? I don't know if it is yet, but it'll be a while until I get there again. I'm pretty new to actually USING Stack Overflow. – cbhedd May 15 '15 at 18:49
  • It worked for us, and we had the exact same issue.. We even started out re-writing code.. One thing you can do to double check if it works or not. Assuming you have multi-dex anabled in your build.gradle defaults, run it on a 5.0 device, it should run fine.. It was anything < 5.0 which could not handle multidex. – Chrispix May 15 '15 at 19:15
  • 1
    Thank you. This saved us. And I like the way you ask questions – Krishnabhadra May 22 '15 at 10:25
  • 1
    Thanks! It seems to have fixed my issue, so I marked it as the right answer. – cbhedd May 22 '15 at 17:34
  • 1
    extending MultiDexApplication solved a similar issue for me. But it was not on pre 5.0 devices, but on pre 4.4.... THANK YOU. – CAA Jan 26 '16 at 07:28
3

I just spent few hours on it, and now got it resolved.

A constraint for some Android apps is the total number of methods that the underlying compiled .dex file can support. It’s limited by 16 bits, or 65,536 values.

When you include third-party libraries in your application, you will have all of their methods in your .dex file. Larger APIs, such as those included in Google Play services, will then begin eating into the limit very quickly.

For More Details: Google Play services and DEX method limits

In my case I was using Google Play Services for Google/Youtube Authentication in my App.

compile 'com.google.android.gms:play-services:7.3.0'

So I changed it to the

compile 'com.google.android.gms:play-services-identity:7.3.0'

as I required it only for Identity/Authentication purpose. So you can select the Individual library according to your requirement.

For example, if all you want to use is Maps, you would instead have:

compile 'com.google.android.gms:play-services-maps:7.3.0'

likewise for location

compile 'com.google.android.gms:play-services-location:7.3.0'

I hope it will help you!

Prankul Garg
  • 3,416
  • 1
  • 17
  • 11