• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

How do I add "extra" classes to Android Studio?

RhinoCan

Well-Known Member
I asked this question on StackExchange and it has been viewed a few times but no one has answered it after several days so I thought I'd try here....

I am new to Android development in general and Android Studio (AS) in particular. I have the current version (3.1.2) installed and it's mostly working well but I'm not very clear on something. I don't have all the terminology yet so forgive me for putting this in a slightly roundabout way.

I gather that AS comes with a certain set of classes to enable me to do a great many standard things. However, in some cases, I will want to add additional classes to AS to do things that are not built into the IDE. This, of course, is expected and allowed for by the developers. However, I'm not clear on how to do so.

For example, I am imitating some code I found in a tutorial and it calls for a Snackbar to be created. I copied in the code that creates the Snackbar but AS highlights the word Snackbar in red. I understand that this means that the Snackbar class isn't built into AS. Even though I have the AS set to generate imports automatically the first time I use a class in a program, that doesn't work for Snackbar and even hand-coding the import doesn't work.

Clearly, I need to do something to add the Snackbar class (and any of its dependencies) to AS. I started poking around and found this reply to a question about adding Snackbar to AS: Android design support library - version number and gradle error. From that response, I learned that the person asking that question knew that he needed to add a dependency but couldn't get the dependency to work and was asking about it.

Now, I'm not as smart/experienced as that person so I'd like to know a few things: 1. If I get a class name highlighted in red, does it ALWAYS mean that I need to add a dependency to Gradle (once I've ruled out spelling errors)? 2. How do I determine WHICH dependency (and LEVEL) needs to be added to Gradle?

There seem to be several Snackbar classes, including android.support.design.widget.Snackbar and https://developer.android.com/reference/com/google/android/material/snackbar/package-summary. How do I know which one I need? I'm guessing that one was an earlier version that was rolled out as a standalone class and that the other is a later version that was more closely integrated with the rest of the class structure but I'm not sure how to tell which is the "latest and greatest". Then, once I know that, I need to find out the name of the dependency that will resolve the issue and then the current highest level of that dependency.

Can someone explain to me how all that is done? I'd be very grateful if someone could help me with that.
 
Can you post the code for the Snackbar class here, in full? Use [code][/code] tags to contain the code.

If you hover over the red highlight, Android Studio should tell you what the problem is.
 
Also, what is the tutorial you're working through?

The tutorial I was working through is actually a bit more advanced than I'm ready for; he briefly mentions the proper way of handling permissions but this is only to set up the gist of his article which is to argue that the processing involved suggests a design pattern which he then goes on to explain. I have no problem with him doing that but I want to understand the basic processing FIRST before throwing that aside in favour of a design pattern that may or may not be better than something I can do myself.

Here's a link to the tutorial:
http://www.truiton.com/2016/04/obtaining-runtime-permissions-android-marshmallow-6-0/

I tried importing his code in the hopes that I could run it in debug and learn how it works but Snackbar references were invariably in red and I can't figure out what I need to do to make it work properly. I assume I need to add a dependency but I'm still very new to Android development and can't figure out which version of the Snackbar class I need, let alone which dependency that is or what *level* of that dependency. (I'm not ever sure where to ADD the dependency: Gradle.build?) I had hoped the documentation would say something like "android.Snackbar.Version1 - requires xxx.yyy.zzz current level 47", possibly with a link so I could actually FIND that but I haven't seen anything like that. I'm sure veteran developers figured all that out ages ago but I'm not even sure where to look for it.

I'm also working through a similar example, which I think the tutorial writer may have borrowed as his starting point, but when I import that one, Snackbar is recognized. I assume it has got the necessary dependency indicated somewhere but I'm having trouble determining what the dependency is and where it is in the project.

Basically, I'm just trying to answer a very general question: if I get my code highlighted in red and it's not a typo, how do I determine which version of the class I need (full name of the class) and what dependency (and what level of that dependency) I need to satisfy Android Studio?

It's HARD learning this stuff entirely on your own when it's a new environment and you don't know what information is available and where to find it! If I was working on a development team, I'd just go find a veteran Android developer, buy him/her a coffee, and pick his/her brains for half hour. But I'm the whole team so I had to use forums like this to fill that role....
 
Can you post the code for the Snackbar class here, in full? Use [code][/code] tags to contain the code.



If you hover over the red highlight, Android Studio should tell you what the problem is.

Here's one chunk of it:
Code:
Snackbar.make(findViewById(android.R.id.content), mErrorString.get(requestCode),
        Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
        new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                startActivity(intent);
            }
        }).show();


Do you need the other bits and pieces? I assume they're all using the same version of Snackbar so I'm not sure why you'd need more....

All that Android Studio tells me when I hover over the red Snackbar text is "cannot resolve symbol 'Snackbar'.
 
Last edited by a moderator:
"Cannot resolve symbol" means the compiler couldn't find the definition of the class, because you didn't have the correct import statement. Did you include this import statement?

Code:
import android.support.design.widget.Snackbar;
 
"Cannot resolve symbol" means the compiler couldn't find the definition of the class, because you didn't have the correct import statement. Did you include this import statement?

Code:
import android.support.design.widget.Snackbar;

That was my theory too. I've already enabled the option that automatically generates Imports for new code so I shouldn't need to hand-code it, right? But I *did* try to hand-code it and Android ERASED it when I did, which I found quite remarkable. Maybe I should make a short video of that too..... ;-)
 
Android Studio will automatically insert the import statements as you type the class names in your code. When there is ambiguity (2 classes with the same name, but in different packages), it will ask you which class to use.
 
Android Studio will automatically insert the import statements as you type the class names in your code. When there is ambiguity (2 classes with the same name, but in different packages), it will ask you which class to use.

That's exactly what I'd expect given my experience with other IDEs, particularly Eclipse. But it's not what actually happens. I've created a short video illustrating the behaviour that I'm getting.

Why won't it let me upload my video? All I get is a very vague error message that says: "There was a problem uploading your file." No word on WHAT the problem was. I've tried uploading .MP4 and .WMV but the same thing happens for both. I'm guessing that either the file format isn't one it will accept or the file is too big but the message is so vague it could be anything.

I have spent HOURS piddling around researching screen recorders, installing and learning to use two of them - the first one didn't work satisfactorily - then learning how to get them into a common format so it's really exasperating being unable to upload the two minute video that proves the behaviour I'm getting so that you know I'm not delusional ;-)
 
I see your problem. You're missing some dependencies. I understand the confusion, and have to admit that the Google Android documentation is somewhat deficient in this regard, because it doesn't mention anything about dependencies. So that leaves you reliant on finding a tutorial example, which includes the required Gradle dependencies. One such example is here:

https://www.androidhive.info/2015/09/android-material-design-snackbar-example/

But let's take a step back here - why are you using Snackbar? It's not a class I've used before, and all it does is display a message to the user, in a dialog window. You'd make life a whole lot simpler for yourself, if you just used the standard Toast dialog. Is there some compelling reason why you need to use Snackbar?
 
Actually having looked into this a bit further, Snackbar does give you more functionality. Specifically the ability to attach an action to the dialog.
It looks like the Snackbar class is provided by a supplementary support library, which is why you need to add the Gradle dependency to allow Android Studio to pick it up

Code:
compile 'com.android.support:design:22.2.0'

Some information about it here

https://android-developers.googleblog.com/2015/05/android-design-support-library.html

and here talking about the material design style

https://androidbycode.wordpress.com...gn-snackbar-using-the-design-support-library/
 
I see your problem. You're missing some dependencies. I understand the confusion, and have to admit that the Google Android documentation is somewhat deficient in this regard, because it doesn't mention anything about dependencies. So that leaves you reliant on finding a tutorial example, which includes the required Gradle dependencies. One such example is here:

https://www.androidhive.info/2015/09/android-material-design-snackbar-example/

But let's take a step back here - why are you using Snackbar? It's not a class I've used before, and all it does is display a message to the user, in a dialog window. You'd make life a whole lot simpler for yourself, if you just used the standard Toast dialog. Is there some compelling reason why you need to use Snackbar?

As far as the dependency goes, I had looked at two (similar) examples in GitHub, both of which included Snackbar. I downloaded/imported them both in the hope of actually running the examples in the debugger so that I could follow exactly what they were doing but the missing dependency kept them from working. As you've said, the documentation on dependencies is somewhat lacking which is why I raised the question on StackExchange. But no one chose to answer it so I found this forum and tried it here. Now I finally have an answer! Hooray!! :-)

As for why I'm using Snackbar, I have no special interest in it. The examples I was studying used it and I did see some claims that Snackbar was better than Toast for uses like mine. You have seen similar information yourself, according to your followup post.

Now, I could have simply used Toast and avoided the issue I was having but I wanted to know how to handle the situation of classes that weren't in the standard version of Android Studio anyway so it seemed to be a perfect example. That's why I asked the question. It seemed to be a "two birds with one stone" question: it would help me with the immediate issue of Snackbar but, more importantly, educate me on how to handle similar issues in the future.
 
Actually having looked into this a bit further, Snackbar does give you more functionality. Specifically the ability to attach an action to the dialog.
It looks like the Snackbar class is provided by a supplementary support library, which is why you need to add the Gradle dependency to allow Android Studio to pick it up

Code:
compile 'com.android.support:design:22.2.0'


Some information about it here

https://android-developers.googleblog.com/2015/05/android-design-support-library.html

and here talking about the material design style

https://androidbycode.wordpress.com...gn-snackbar-using-the-design-support-library/

That code snippet is exactly the information I've been trying to get. Now, two followup questions:
1. I see that you got the name of the dependency from the various articles and settled on version 22.2.0 despite the version numbers being slightly different in each of the articles you've cited. I assume the code in these dependencies gets updated periodically, leading to various different versions. How can I determine "the latest and greatest" version of a given dependency so that I'm not running on old/buggy code? I

2. Also, one of the articles you cited said specifically to put the dependency in the gradle.build file. That's VERY useful to know but inspires another question: what is the difference between the two gradle.build files I have? One has "(Project: name-of-my-project)" after it and a comment to say that my dependencies DON'T go in there (although there are other dependencies there) and the other has "(Module: app)" and an area to add dependencies. Having two files with the same name and similar (?) but different purpose is pretty confusing. (I have to wonder why the designers chose to given them the same name but I assume they had a good reason.)

For what it's worth, I added the exact line you specified in your earlier reply to my second gradle.build file. It suggested that things might be out of sync so I clicked on File->Sync Project with Gradle Files. Unfortunately, that caused TWO errors that I don't really understand. One of the errors was on a line that was already there, namely
Code:
implementation 'com.android.support:appcompat-v7:27.1.1'
The error is rather lengthy and I can't figure out how to copy/paste it. It says something about all com.android.support libraries needing to be the exact same level.

This line is also marked as an error:
Code:
compile 'com.android.support:design:22.2.0'


I'm also getting this in the right hand pane in the window below the gradle.build file:
Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html

I don't fully understand ANY of these errors but I made the second error go away by changing the level to 27.1.1 from 22.2.0. I also changed the "compile" to "api" (I read the link in the third error message but I really don't understand if I want "implementation" or "api" instead of "compile". I know the former performs better but I don't know if it does what I need it to do. Please advise.)

In any case, the *first* error does NOT go away so now I can't run my program even though I didn't add that line. What do I do about that?
 
I think it may help if I try this myself, and I can tell you the exact combination of dependencies/versions that you need to get this working.
 
I think it may help if I try this myself, and I can tell you the exact combination of dependencies/versions that you need to get this working.

I think itmight be very helpful if you can do that. I'm starting to suspect that the Android build tools version in build.gradle needs to be 27.0.3, at least for me and my version of Android Studio, because it insisted I change that from the 24.0 that was in the code I copied from GitHub. (Much to my surprise, it didn't force me to raise the levels on the dependencies to match: I was starting to think they all had to be at the same level from things I saw in another app.)
 
I created a brand new app project in Android Studio. The following build.gradle works for me, and I'm able to use the Snackbar class in my code.
Key points to be aware of:
  • compileSdkVersion (27) must be the same as your support.appcompat major version

  • The versions of your support library dependencies must agree with those used in the test framework dependencies, otherwise you get a clash, and your project won't build.

  • These two items must use the same version

Code:
implementation 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support:design:27.1.1'

Here's my full build.gradle file:

Code:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.acme.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.1'
    compile 'com.android.support:design:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


Just to give you some background on these kind of problems - historically the building of Java applications has been difficult, whenever you try to use third party libraries, which have their own dependencies. They are technically called 'transitive dependencies'. This is why build dependency management tools were invented, like Maven, and more recently Gradle. They generally do a good job of sorting out this version dependency hell, but as you can see, it's not perfect.
I do however think that Android Studio gives you a lot of useful help in sorting out these problems.

Generally you are better off obtaining the most recent versions of any libraries you wish to use in your project. That's why you can run into problems when you use an older project, with possibly outdated dependency versions. Incidentally, Android Studio will actually tell you, when you hover over, if there's a newer minor point version of any library you're using e.g. 27.0.1 vs 27.1.1.
 
I created a brand new app project in Android Studio. The following build.gradle works for me, and I'm able to use the Snackbar class in my code.
Key points to be aware of:
  • compileSdkVersion (27) must be the same as your support.appcompat major version

  • The versions of your support library dependencies must agree with those used in the test framework dependencies, otherwise you get a clash, and your project won't build.

  • These two items must use the same version

Code:
implementation 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support:design:27.1.1'

Here's my full build.gradle file:

Code:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.acme.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.1'
    compile 'com.android.support:design:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


Just to give you some background on these kind of problems - historically the building of Java applications has been difficult, whenever you try to use third party libraries, which have their own dependencies. They are technically called 'transitive dependencies'. This is why build dependency management tools were invented, like Maven, and more recently Gradle. They generally do a good job of sorting out this version dependency hell, but as you can see, it's not perfect.
I do however think that Android Studio gives you a lot of useful help in sorting out these problems.

Generally you are better off obtaining the most recent versions of any libraries you wish to use in your project. That's why you can run into problems when you use an older project, with possibly outdated dependency versions. Incidentally, Android Studio will actually tell you, when you hover over, if there's a newer minor point version of any library you're using e.g. 27.0.1 vs 27.1.1.

I'm going to need a bit of time to digest that and think of my followup questions (I almost always do). I'm studying RecyclerView now and there's a lot to it....
 
I'm going to need a bit of time to digest that and think of my followup questions (I almost always do). I'm studying RecyclerView now and there's a lot to it....

There certainly is. It's important to understand the key concepts of View recycling, and View holders.
Incidentally, RecyclerView is an evolution of the standard ListView, in which it was the developer's responsibility to code it in an efficient way, using the ViewHolder pattern. So important was this, that they released the RecyclerView, which has that pattern baked into it.
 
2. Also, one of the articles you cited said specifically to put the dependency in the gradle.build file. That's VERY useful to know but inspires another question: what is the difference between the two gradle.build files I have? One has "(Project: name-of-my-project)" after it and a comment to say that my dependencies DON'T go in there (although there are other dependencies there) and the other has "(Module: app)" and an area to add dependencies. Having two files with the same name and similar (?) but different purpose is pretty confusing. (I have to wonder why the designers chose to given them the same name but I assume they had a good reason.)

Just attempting to clear up the confusion here - You have two build.gradle files in your project, but they are at different levels in your folder structure. There's a top level build.gradle, which includes the other one. It's very similar to Maven (if you've had experience with that), where there's a hierarchical structure. This allows you to create a project which has several sub-modules/projects which all get built and packaged together. Basically it facilities better modularity, if you need it.

So the top level build.gradle file really doesn't have much in it, and there's a properties file that specifies exactly which modules to include. The build.gradle file you are primarily concerned with is the one which lives in the module folder. This is where you add your dependencies.
 
Back
Top Bottom