So today I was working on my App, everything was working okay until all the sudden Universal Image Loader and MultiDex stopped working, all my other imports were ok but just these two, I try removing the imports and re-imported them they could not work, here is my Application class that is suffering from the import issue:
public class App extends Application {
private static App instance;
public static Context applicationContext=null;
public static volatile Handler applicationHandler = null;
public static Point displaySize = new Point();
public static float density = 1;
public Bitmap cropped = null;
public Uri imgLocation = null;
public String imgePath = null;
#Override public void onCreate() {
super.onCreate();
initImageLoader();
instance = this;
mInstance = this;
applicationContext = getApplicationContext();
applicationHandler = new Handler(applicationContext.getMainLooper());
checkDisplaySize();
density = App.applicationContext.getResources().getDisplayMetrics().density;
DisplayImageOptions defaultDisplayImageOptions = new DisplayImageOptions.Builder() //
.considerExifParams(true)
.resetViewBeforeLoading(true)
.showImageOnLoading(R.drawable.nophotos)
.showImageOnFail(R.drawable.nophotos)
.delayBeforeLoading(0)
.build(); //
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.defaultDisplayImageOptions(defaultDisplayImageOptions)
.memoryCacheExtraOptions(480, 800).threadPoolSize(5).build();
ImageLoader.getInstance().init(config);
}
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
And my Gradle File:
dependencies {
compile project(':ImageViewTouch')
compile project(':Gpu-Image')
compile project(':fastjson-1.2.5')
compile project(':android-support-multidex')
compile project(':universal-image-loader-1.9.4')
}
This answer is based off of the fact that you said:
Everything was working okay until all the sudden
Okay, so if everything was working before, it is not your fault, but android-studios fault.
Here are some things that you can try to do to fix it:
Clean project
Rebuild Project
Restart IDE
Update SDK tools
This is probably not an issue with your code, so you don't have to worry about it much. If cleaning and rebuilding doesn't work, just wait for some time.
Give android studio a while to set up, and this could take a few minutes. Often times, it fixes itself without even having to do any of the steps I listed above.
IMPORTANT:
ONLY update your SDK or mess with files AS THE LAST STEP. If you do that, I HIGHLY suggest you take a backup first.
Many times, this error appears when there is an error on the file to be imported. So open the file to be imported and correct any errors in there first.
If the error still persists, right click on the project and select the option 'Analyse' > 'Code Cleanup'
also,
make sure your package directory structure does not have any uppercase letters
Related
I'm following this tutorial and this Custom Detector Example in order to implement Custom Lint Rules. Basically what I've done is:
Create a new Android Project in Android Studio;
Create a java module for project created in step 1;
On module's build.gradle, import Lint API dependencies;
Create an Issue & IssueRegistry & CustomDetector;
Reference the IssueRegistry on module's build.gradle;
Create Unit tests;
My problem is, during the execution of my JUnits, I always receive "No Warning". When I debug the test, I can see that my Custom Detector isn't called, what am I doing wrong?
Strings.java
public class Strings {
public static final String STR_ISSUE_001_ID = "VarsMustHaveMoreThanOneCharacter";
public static final String STR_ISSUE_001_DESCRIPTION = "Avoid naming variables with only one character";
public static final String STR_ISSUE_001_EXPLANATION = "Variables named with only one character do not pass any meaning to the reader. " +
"Variables name should clear indicate the meaning of the value it is holding";
}
Issues.java
public class Issues {
public static final
Issue ISSUE_001 = Issue.create(
STR_ISSUE_001_ID,
STR_ISSUE_001_DESCRIPTION,
STR_ISSUE_001_EXPLANATION,
SECURITY,
// Priority ranging from 0 to 10 in severeness
6,
WARNING,
new Implementation(VariableNameDetector.class, ALL_RESOURCES_SCOPE)
);
}
IssuesRegistry.java
public class IssueRegistry extends com.android.tools.lint.client.api.IssueRegistry {
#Override
public List<Issue> getIssues() {
List<Issue> issues = new ArrayList<>();
issues.add(ISSUE_001);
return issues;
}
}
VariableNameDetector.java
public class VariableNameDetector extends Detector implements Detector.JavaScanner {
public VariableNameDetector() {
}
#Override
public boolean appliesToResourceRefs() {
return false;
}
#Override
public boolean appliesTo(Context context, File file) {
return true;
}
#Override
#Nullable
public AstVisitor createJavaVisitor(JavaContext context) {
return new NamingConventionVisitor(context);
}
#Override
public List<String> getApplicableMethodNames() {
return null;
}
#Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
List<Class<? extends Node>> types = new ArrayList<>(1);
types.add(lombok.ast.VariableDeclaration.class);
return types;
}
#Override
public void visitMethod(
JavaContext context,
AstVisitor visitor,
MethodInvocation methodInvocation
) {
}
#Override
public void visitResourceReference(
JavaContext context,
AstVisitor visitor,
Node node,
String type,
String name,
boolean isFramework
) {
}
private class NamingConventionVisitor extends ForwardingAstVisitor {
private final JavaContext context;
NamingConventionVisitor(JavaContext context) {
this.context = context;
}
#Override
public boolean visitVariableDeclaration(VariableDeclaration node) {
StrictListAccessor<VariableDefinitionEntry, VariableDeclaration> varDefinitions =
node.getVariableDefinitionEntries();
for (VariableDefinitionEntry varDefinition : varDefinitions) {
String name = varDefinition.astName().astValue();
if (name.length() == 1) {
context.report(
ISSUE_001,
context.getLocation(node),
STR_ISSUE_001_DESCRIPTION
);
return true;
}
}
return false;
}
}
}
build.gradle
apply plugin: 'java'
configurations {
lintChecks
}
ext {
VERSION_LINT_API = '24.3.1'
VERSION_LINT_API_TESTS = '24.3.1'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.tools.lint:lint-api:$VERSION_LINT_API"
implementation "com.android.tools.lint:lint-checks:$VERSION_LINT_API"
testImplementation "com.android.tools.lint:lint-tests:$VERSION_LINT_API_TESTS"
}
jar {
manifest {
attributes('Lint-Registry': 'br.com.edsilfer.lint_rules.resources.IssueRegistry')
}
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
TestVariableNameDetector.java
private static final String ARG_DEFAULT_LINT_SUCCESS_LOG = "No warnings.";
#Override
protected Detector getDetector() {
return new VariableNameDetector();
}
#Override
protected List<Issue> getIssues() {
return Collections.singletonList(Issues.ISSUE_001);
}
public void test_file_with_no_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test.java", "public class Test {public String sampleVariable;}"))
);
}
public void test_file_with_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test3.java", "public class Test {public String a;bnvhgvhj}"))
);
}
}
P.S.: on Java's module I do not have access to assetsor res folder, that is the reason why I've created a String.java and I'm using java(to, source) in my Unit test - I assumed that this java method does the same as the xml from the tutorial link I referenced at the top of this question.
It turned out that in my case the problem was with the JUnit itself. I think that the way I was attempting to simulate the file was wrong. The text below is part of the README.md of a sample project that I've created in order to document what I've learned from this API and answers the question in the title:
Create
Create a new Android Project;
Create a new Java Library Module - Custom Lint Rules are packaged into .jar libraries once they are ready, therefore the easiest way to implement them using them is inside a Java Module Library;
On module's build.gradle:
add target and source compatibility to Java 1.7;
add dependencies for lint-api, lint-checks and test dependencies;
add jar packing task containing two attributes: Manifest-Version and Lint-Registry, set the first to 1.0 and the second as the full path to a class that will later on contain the issue's catalog;
add a default tasl assemble;
[OPTIONAL]: add a task that will copy the generated .jar into ~/.android/lint;
Check REF001 and choose a Detector that best suits your needs, based on it create and implement a class to fulfill the Detector's role;
Still based on REF0001 chosen file, create and implement a Checker class, later referring to it inside Detector's createJavaVisitor() method;
for the sake of SRP, do not place Checker in the same file of Detector's class;
Copy the generated .jar file from build/lib to ~/.android/lint - if you added a task on build.gradle that does this you can skip this step;
Restart the computer - once created and moved into ~/.android/lint, the Custom Rules should be read by Lint next time the program starts. In order to have the alert boxes inside Android Studio, it is enough to invalidate caches and restart the IDE, however, to have your custom rules caught on Lint Report when ./gradlew check, it might be necessary to restart your computer;
Testing Detectors and Checkers
Testing Custom Rules is not an easy task to do - mainly due the lack of documentation for official APIs. This section will present two approaches for dealing with this. The main goal of this project is to create custom rules that will be run against real files, therefore, test files will be necessary for testing them. They can be places in src/test/resources folder from your Lint Java Library Module;
Approach 01: LintDetectorTest
Make sure you've added all test dependencies - checkout sample project's build.gradle;
Copy EnhancedLintDetectorTest.java and FileUtils.java into your project's test directory;
There is a known bug with Android Studio that prevents it from seeing files from src/test/resources folder, these files are a workaround for that;
EnhancedLintDetectorTest.java should return all issues that will be subject of tests. A nice way to do so is getting them from Issue Registry;
Create a test class that extends from EnhancedLintDetectorTest.java;
Implement getDetector() method returning an instance of the Detector to be tested;
Use lintFiles("test file path taking resources dir as root") to perform the check of the Custom Rules and use its result object to assert the tests;
Note that LintDetectorTest.java derives from TestCase.java, therefore, you're limited to JUnit 3.
Approach 02: Lint JUnit Rule
You might have noticed that Approach 01 might be a little overcomplicated, despite the fact that you're limited to JUnit 3 features. Because of that GitHub user a11n created a Lint JUnit Rule that allows the test of Custom Lint Rules in a easier way that counts with JUnit 4 and up features. Please, refer to his project README.md for details about how to create tests using this apprach.
Currently, Lint JUnit Rule do not correct the root dir for test files and you might no be able to see the tests passing from the IDE - however it works when test are run from command line. An issue and PR were created in order to fix this bug.
I'm not sure how to use the AST Api, however I'm personally using Psi and this is one of my lint checks that are working for me.
public final class RxJava2MethodCheckReturnValueDetector extends Detector implements Detector.JavaPsiScanner {
static final Issue ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE =
Issue.create("MethodMissingCheckReturnValue", "Method is missing the #CheckReturnValue annotation",
"Methods returning RxJava Reactive Types should be annotated with the #CheckReturnValue annotation.",
MESSAGES, 8, WARNING,
new Implementation(RxJava2MethodCheckReturnValueDetector.class, EnumSet.of(JAVA_FILE, TEST_SOURCES)));
#Override public List<Class<? extends PsiElement>> getApplicablePsiTypes() {
return Collections.<Class<? extends PsiElement>>singletonList(PsiMethod.class);
}
#Override public JavaElementVisitor createPsiVisitor(#NonNull final JavaContext context) {
return new CheckReturnValueVisitor(context);
}
static class CheckReturnValueVisitor extends JavaElementVisitor {
private final JavaContext context;
CheckReturnValueVisitor(final JavaContext context) {
this.context = context;
}
#Override public void visitMethod(final PsiMethod method) {
final PsiType returnType = method.getReturnType();
if (returnType != null && Utils.isRxJava2TypeThatRequiresCheckReturnValueAnnotation(returnType)) {
final PsiAnnotation[] annotations = method.getModifierList().getAnnotations();
for (final PsiAnnotation annotation : annotations) {
if ("io.reactivex.annotations.CheckReturnValue".equals(annotation.getQualifiedName())) {
return;
}
}
final boolean isMethodMissingCheckReturnValueSuppressed = context.getDriver().isSuppressed(context, ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE, method);
if (!isMethodMissingCheckReturnValueSuppressed) {
context.report(ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE, context.getLocation(method.getNameIdentifier()), "Method should have #CheckReturnValue annotation");
}
}
}
}
}
Checkout the many more I wrote here.
Firstly, I have to say that I am just a beginner with the Android programming, and I may not understood things correctly. ^^
Secondly, my problem is that the R file (the one which create the different IDs of the objects) just stopped to create new ones.
I noticed that when I created a new image_button at the main_layout and when I tried to look for it on the MainActivity it wrote that it didn't exist.
Moreover, only after I modify the R file (which I should not touch according to the system warning), I have control over the new IDs.
And after breaking my head for two days - I decided to ask you,
The R file:
public final class R {
public static final class attr {
}
public static final class dimen {
/* Default screen margins, per the Android Design guidelines.
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
*/
public static final int activity_horizontal_margin = 0x7F040000;
public static final int activity_vertical_margin = 0x7F040001;
}
public static final class drawable {
public static final int ic_launcher = 0x7F020000;
public static final int loading_i = 0x7F020001;
}
public static final class id {
public static final int action_settings = 0x7F080004;
public static final int button1 = 0x7F080001;
public static final int imbt = 0x7F080003;
public static final int textView1 = 0x7F080000;
public static final int tv1 = 0x7F080002;
}
public static final class layout {
public static final int activity_main = 0x7F030000;
public static final int firstpage = 0x7F030001;
public static final int loading_screen = 0x7F030002;
}
public static final class menu {
public static final int main = 0x7F070000;
}
public static final class string {
public static final int action_settings = 0x7F050001;
public static final int app_name = 0x7F050000;
public static final int hello_world = 0x7F050002;
}
The creation of the new object:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/imgBtn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Yep, you shouldn't edit the R file directly. The problem you meet is normal. It should be causes by a file out of sync.
Hopefully, you could fix it by:
Option #1: Try to refresh whole project and 'Project -> build project'.
Option #2: If #1 doesn't work, hit 'Project - clean...', and then rebuild the project.
Option #3: Sometimes, #1 and #2 don't work. The last ultimate way,
which always works for me, is to delete the `gen` folder and rebuild the project.
Make sure that
Project --> Build Automatically
If it's already checkedm, run clean:
Project --> clean
If that doesn't work, then most likely there is an error in one of the files, most likely one of the layout XML files. Check the Problems view:
Window --> Show View --> Problems.
Fix all the problems (you can ignore the warnings).
Your last resort is to delete the R file (backup first) and then re-built (or clean).
It's one of the most common problems beginners face; even I faced this too. :)
The most obvious solution is to try cleaning and building your project. Sometimes it works, and most of the times it doesn't.
When cleaning and building doesn't work, then most likely you have some error in your code and that too in XML files. Android tools sometimes don't show which XML file has the error, so you manually need to open each file and check for errors. Once you have fixed the errors, your R.java will build automatically.
I hope this helps.. :)
Update:
This used to happen for Eclipse and ADT plugin. Android Studio is the savior. Start using it if you aren't already.
Clean your project and run it:
Project---> Clean then run
See Stack Overflow question Developing for Android in Eclipse: R.java not generating. It gives the perfect solution for you...
Change the build target version and clean the project. After completing that, change that build version to previous. It works for me.
So after spending a day or so trying to get robolectric to work with gradle using the android-gradle-plpugin I read that the creator thinks it's too much hassle and doesn't use it himself
So thats a big enough reason for me not to use it either. However now I cannot find any docs on how to set up normal android tests to run on the emulator. Its seems they all relate to eclipse. How do I get normal Android testings running with Android studio. I presume I need to modify build.gradle but how do I do that?
I would also like to use roboguice to inject my dependencies into the test cases.
EDIT
So I took a stab in the dark and I tried this but the test returns false (a fail)
public class SearchTest extends ActivityTestCase {
#Inject
private ObjectMapper objectMapper;
#Override
protected void setUp() throws Exception {
super.setUp();
RoboInjector injector = RoboGuice.getInjector(getActivity());
injector.injectMembersWithoutViews(this);
}
public void shouldSerialise() {
System.out.println("called should serialise");
Assert.assertNotNull(objectMapper);
}
}
EDIT 2
So I have tried a different approach. I followed this tutorial which does seem to run the test however I am having a problem with providing a manifest find as I get the following error,
WARNING: No manifest file found at ./AndroidManifest.xml.Falling back
to the Android OS resources only. To remove this warning, annotate
your test class with #Config(manifest=Config.NONE).
I then used this test runner instead...
public class RobolectricGradleTestRunner extends RobolectricTestRunner {
public RobolectricGradleTestRunner(Class<?> testClass) throws org.junit.runners.model.InitializationError {
super(testClass);
}
#Override protected AndroidManifest getAppManifest(Config config) {
String manifestProperty = System.getProperty("android.manifest");
if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
String resProperty = System.getProperty("android.resources");
String assetsProperty = System.getProperty("android.assets");
return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
Fs.fileFromPath(assetsProperty));
}
return super.getAppManifest(config);
}
}
With no luck. Would I be better reverting back to intellij and purely using maven?
I followed the exact steps given in the post below:
Is it possible to dynamically load a library at runtime from an Android application?
I am using and android 2.2 phone for testing and getting an error which is driving me crazy :(
07-27 01:24:55.692: W/System.err(14319): java.lang.ClassNotFoundException: com.shoaib.AndroidCCL.MyClass in loader dalvik.system.DexClassLoader#43abbc20
Can someone help me what to do now..i have tried various suggested solutions on different posts
I was wondering whether this was feasible so I wrote the following class:
package org.shoaib.androidccl;
import android.util.Log;
public class MyClass {
public MyClass() {
Log.d(MyClass.class.getName(), "MyClass: constructor called.");
}
public void doSomething() {
Log.d(MyClass.class.getName(), "MyClass: doSomething() called.");
}
}
And I packaged it in a DEX file that I saved on my device's SD card as /sdcard/testdex.jar.
Then I wrote the program below, after having removed MyClass from my Eclipse project and cleaned it:
public class Main extends Activity {
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
final String libPath = Environment.getExternalStorageDirectory() + "/testdex.jar";
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("org.shoaib.androidccl.MyClass");
final Object myInstance = classToLoad.newInstance();
final Method doSomething = classToLoad.getMethod("doSomething");
doSomething.invoke(myInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I guess your problem lies on the way you package MyClass in a DEX. How do you do that?
I followed Shlublu's thread and tried myself and succeeded. I don't know how to "package MyClass in a DEX", so I simply build an android apk and put it in the sdcard. And the code worked.
Are you wraping MyClass in a classes.dex? DexClassLoader will only look for classes.dex in your jar/dex. Maybe you can first try what I did (build an signed apk instead of jar, but you don't need to install the apk), and see if it's working. Hope this helps!
I have a problem with my code which refuses to go away. This is the first half of my code:
public class SampleGame extends AndroidGame {
public static String map;
boolean firstTimeCreate = true;
#Override
public Screen getInitScreen() {
if (firstTimeCreate) {
Assets.load(this);
firstTimeCreate = false;
}
InputStream is = getResources().openRawResource(R.raw.map1);
map = convertStreamToString(is);
return new SplashLoadingScreen(this);
}
An error message is generated on the line
InputStream is = getResources().openRawResource(R.raw.map1)
The error message says I should add the line "import android.R", but when I do this, a second error message is generated which says "map1 cannot be resolved or is not a field." Can someone please give me any suggestions on how to solve this intractable problem?
Be sure that there is map1 in Raw folder.If it exists,then try clean/build your project or close and reopen eclipse.It may be solved.
Try updating your Eclipse android ADT to the latest, restart it.
Im not very good at android but if yours does have an onCreate some where make sure u reference your Resources after it has done the onCreate stuff.