Rendering issues: The following classes cannot be instantiated - android

I am converting a Eclipse project to work in Android Studio and have got all issues fixed except some layout xmls are showing the following issue in the drag and drop view
Rendering issues: The following classes cannot be instantiated
X.X.X.myclass.
I checked my class and it seems ok, i changed the latest API i have from the little dropdown; 22 (i guess this is the compile API). I havnt changed my Gradle setup, could it be something in there?
I havnt posted any code as im not sure what would be helpful - any ideas?

First of all: that's just a layout preview. You can edit the XML and carry on with your project and it won't affect anything on it.
The layout rendering thing literally runs your Java classes to create the preview with some mocked implementation or an actual android device, similar to testing mocked implementations.
So this message is just telling you that this mocked system failed to render the preview.
But if you really want to see the preview, you must check where in your class are you relying on variables, or objects that are inherent from your app that the mock system will not have access to.
An example, if your custom view does some special stuff during onLayout:
#Override onLayout(...){
int value = MyLayoutDetailsCalculation.getExtraPadding(getContext());
}
that is a code that is calling to a static method on a separate class that is using the context (probably getting values from system resources or from the display manager) and this will not execute well in a mocked environment and the preview wouldn't be able to render it.
luckly it's an easy fix:
#Override onLayout(...){
int value;
if(isInEditMode()){ // that returns true if this code is being executed by AndroidStudio mocked system.
value = 0; // any value that makes OK for your custom class to properly show a preview
} else {
value = MyLayoutDetailsCalculation.getExtraPadding(getContext());
}
}

Related

How can I tell, in onDraw, whether or not I'm inside Android Studio?

I have a custom view that renders part of itself (pink area) in onDraw. It does this, via a class instance set via adapter/binding. I have no problem with the 117 and details controls at design time. However, this pink area is resulting in a call to onDraw within Android Studio.
Everything's ok at runtime. However, I am getting (and rightfully so) an Android Studio error message - because the class that I use to do the drawing hasn't been instantiated.
So, my question is:
Can I detect, in code, whether or not the app is running (rendering really) inside AS (as opposed to having been deployed to an emulator or device)?**
It might be something like if (BuildConfig.DEBUG), or perhaps something [entirely] different. (There's certainly nothing [else] in the BuildDebug instance that'll help.)
Ultimately, I see my current
override fun onDraw(canvas: Canvas) {
:
:
puzzle.doSomething
replaced with something like:
if (!INSIDE_ANDROID_STUDIO)
puzzle.doSomething
I spent over an hour searching online. With no luck. It's hard to ask "How do I know if I'm running in the Android Studio IDE?" and not get a bazillion links concerning:
Why isn't Android Studio running [correctly]
How to tell if another app is running
How to tell if your app is in the fore or background
Why this or that isn't rendering correctly
But nothing on point. I did numerous searches of "UninitializedPropertyAccessException" and "Render problem" as well.
You can do it by checking what returns the isInEditMode() method. If true your view is displayed in AS or other tool, otherwise - it`s on a device.
Indicates whether this View is currently in edit mode. A View is usually in edit mode when displayed within a developer tool. For instance, if this View is being drawn by a visual user interface builder, this method should return true.
https://developer.android.com/reference/android/view/View#isInEditMode()

Android Wear: Cannot Resolve Image Reference

Probably a stupid question here but I just started programming in Android so bear with me.
https://gist.github.com/gabrielemariotti/ca2d0a9f79b902b19a65
I'm following this project to implement a GridViewPager on my Android Wear application. It works fine, only the background images I'm trying to use are not displaying. It only displays a black screen.
The issue is this getBackground() method, the imageReference in particular.
public ImageReference getBackground(int row, int col) {
SimplePage page = ((SimpleRow)mPages.get(row)).getPages(col);
return ImageReference.forDrawable(page.mBackgroundId);
}
The tutorial shows that an Image Reference should be returned however I am getting build errors saying that ImageReference cannot be resolved. So would I have to create a class or interface for ImageReference? Or do you set an attribute on the images themselves?
Can anyone shed any light on this?
Cheers in advance.
As of version 1.1 of the Wearable Support Library (which FragmentGridPagerAdapter is part of), the methods have changed quite a bit: they no longer use any sort of ImageReference class - the new method, getBackgroundForPage, simply returns a Drawable.

Shadow a part of the Fragment hierarchy

I am a newbie at robolectric unit testing, i have a fragment which i want to test, ex, ScreenAFragment. This has a hierarchy as below,
ScreenAFragment -> MyAppFragment -> MyLibFragment -> SherlockFragment.
There are 2 problems,
The MyLibFragment has some code which links to a database and does other stuff which don't need to be tested as a 'unit test case'.
This MyLibFragment reference is also causing a "PackageManager#NameNotFoundException"
How do I go about testing this? My initial thought was create a ShadowMyLibFragment and config my test case #config(shadow={ShadowMyLibFragment.class}) to use this instead of the original class. Doesn't seem to be working at the moment, as it still seems to refer to the original library and throws the old error.
Any Solutions? I am using Robolectric 2.4 version.

Unittesting AsyncTaskLoader with getLoaderResultSynchronously

I am trying to create unit tests for a REST client that does some API calls. The client works fine in the live application, but I can't get it to run in the test case.
Apparantly, LoaderTestCase.getLoaderResultSynchronously() could be used here (at least according to Android reference, but it will not accept my loader. The code:
public void testGetEventInfo() {
// Init some vars
...
// Create & execute loader
RESTLoader loader = new RESTLoader(getContext(),
RESTLoader.HTTPVerb.GET, action, params, LOADER_GET_NEWS);
getLoaderResultSynchronously(loader);
}
This yields the error getLoaderResultSynchronously(Loader) in the type LoaderTestCase is not applicable for the arguments (RESTLoader).
RESTLoader extends AsyncLoader. Note that I'm using the supportlibrary, maybe the Loader in there is incompatible? The documentation gives no information on this.
I've tried to solve this in several ways, though none seem to work:
Registered a listener to loader. However, the callback never triggers
Using CountdownLatch (also with a listener). Again, no trigger/countdown timeout.
Playing around with the type template (), without success.
Similar solutions on SO, though again failing to reach the listener.
Does anybody know why getLoaderResultSynchronously will not accept the loader? Or another clean way of testing the Loader, including a way to test return data? I can test handling the return data in a separate case, but I would also like to test the actual data.
Sincerely,
Have you taken a look at the source code? You'll find the following import statements:
import android.content.Loader;
import android.content.Loader.OnLoadCompleteListener;
It doesn't look like Android offers a support version for LoaderTestCase. The easiest solution would be to temporarily change to the non-support LoaderManager (that is, have your class make use of the android.content.Loader instead), test your app, and then switch back to the support implementation. You might also consider copying the testing source code into your project, import the support LoaderManager, and execute it directly. I'm not familiar with the test libraries for Loaders but it doesn't seem outwardly obvious that this would cause any major issues.
You can get sources from LoaderTestCase here, create SupportLoaderTestCase class from that sources in your test project and modify all namespaces to support library namespaces (e.g. change android.content.Loader with android.support.v4.content.Loader). Than you can extend your test case from SupportLoaderTestCase (not from LoaderTestCase) and use it without problems
The method you are trying to call (getLoaderResultSynchronously) accepts an object of type android.content.Loader. If your RESTLoader class is not of that EXACT type then you will get this error. I suspect your class directly or indirectly extends android.support.v4.content.Loader, which would explain the error.
I am not aware of a back-port of LoaderTestCase that would support testing of this type of class.

Robolectric Custom Shadow Object

OOTB, Robolectric does not support Locales that well. Therefore, if your app is dependent on locales (which a lot of apps are if they are i18n'nd properly) this can be a royal pain. Long story short, I created my own ShadowFooGeocoder and ShadowFooAddress that allow me to simulate the locale I want. They're basically re-implementations of the existing shadows.
However, when I bind my class as such: bindShadowClass(ShadowFooGeocoder.class), this works great. At runtime, the correct shadow is returned. The problem is that I want to set up the simulations on this object and I'm not sure how. shadowOf(instance) where instance is an injected GeoCoder returns ShadowGeoCoder. I've tried working directly with the ShadowWrangler, but that also returns a ShadowGeocoder.
How can I get at my shadowed class that I've bound through the bindShadowClass(...) call so I can set my expectations (simulations)?
Note: This is a repost of the same question on the Robolectric group here. I posted here because my success rate of getting anyone to answer questions on the group is fairly low. I'm hoping for a better result here.
What I've basically done here is extend ShadowGeocoder like this:
#SuppressWarnings({"UnusedDeclaration"})
#Implements(Geocoder.class)
public class ShadowFooBarGeocoder extends ShadowGeocoder {
// implementation stuff
}
Then I would bind it using the bindShadowClasss(...) and when I retreive the shadow via the static shadowOf(...) call I get back a "ShadowGeocoder" which is an instance of ShadowFooBarGeocoder. I then cast it to that type and perform whatever work I need to.

Categories

Resources