java.lang.NoClassDefFoundError on API level 11 - android

I am facing an error whilst using API level 11.
My app crashes with the following: java.lang.NoClassDefFoundError: com.question.question.BitmapCache only when I use my app with a device running api level 11:
I have Google'd this ofcourse and have tried every solution I have came across but still no luck.
Here is the line where it says there's a problem with in Logcat:
public GoogleCardsAdapter(final Context context) {
mContext = context;
mMemoryCache = new BitmapCache(); //<---- This line here
}
Here's the bitmap cache class:
public class BitmapCache extends LruCache<Integer, Bitmap> {
private static final int KILO = 1024;
private static final int MEMORY_FACTOR = 2 * KILO;
public BitmapCache() {
super((int) (Runtime.getRuntime().maxMemory() / MEMORY_FACTOR));
}
#Override
protected int sizeOf(final Integer key, final Bitmap value) {
return value.getRowBytes() * value.getHeight() / KILO;
}
}
I am using a few libs as well:
If anyone knows what is going wrong here, that would be much appreciated.

Presumably, you are trying to use android.util.LruCache, which only exists in API Level 12 and above.
Consider switching to android.support.v4.util.LruCache from the Android Support package, which will work going back to API Level 4.
Also, please undo your manual modifications of your build path, and copy the Picasso and ListViewAnimations JARs into your project's libs/ directory, so the JARs are on both your build path and packaged into the APK for distribution.

Related

What is LeastRecentlyUsedCacheEvictor in ExoPlayer?

I am very confused with exoplayer and their documentation, They have explained everything in very short.
Can anyone please tell me what exactly leastRecentlyUsedCacheEvictor is and how it work? use case and methods?
ExoPlayer video cache uses a CacheEvictor instance to tell the library when to delete cached files. LeastRecentlyUsedCacheEvictor as the name represents declares that policy in a least recently used order.
Assuming you have watched video A, B, C, A (again) and D (order matters) and you hit the maximum cache capacity passed in LeastRecentlyUsedCacheEvictor constructor. The evictor instance lists the cache usages and finds video B as the least recently used one and deletes it to free space.
Here is a simple usage example:
public class VideoCacheSingleton {
private static final int MAX_VIDEO_CACHE_SIZE_IN_BYTES = 200 * 1024 * 1024; // 200MB
private static Cache sInstance;
public static Cache getInstance(Context context) {
if (sInstance != null) return sInstance;
else return sInstance = new SimpleCache(new File(context.getCacheDir(), "video"), new LeastRecentlyUsedCacheEvictor(MAX_VIDEO_CACHE_SIZE_IN_BYTES), new ExoDatabaseProvider(context)));
}
}

How does Snapchat detect XPosed Framework?

I tried to install Snapchat on my newly rooted and Xposed smartphone. But the login is impossible as Snapchat detects Xposed Framework.
I "understand" the reason of this restriction, even though I think it's a bit too much as I don't use Xposed for Snapchat.
But my question is: How do they detect the Framework ?
SnapChat uses Google's SafetyNet Attestation API and does not specifically check if XPosed is installed. SnapChat runs SafetyNet the first time the app is launched.
To make sure SnapChat does not specifically check for the XPosed framework, I decompiled Snapchat and ran grep -lri xposed. The search came up with no results.
Checking if XPosed is installed:
I'm sure there are plenty of ways you could check if Xposed is installed. I wrote the following method which gets the currently installed Xposed version or returns null if the XposedBridge.jar was not found on the device:
/**
* Get the current Xposed version installed on the device.
*
* #param context The application context
* #return The Xposed version or {#code null} if Xposed isn't installed.
*/
public static Integer getXposedVersion(Context context) {
try {
File xposedBridge = new File("/system/framework/XposedBridge.jar");
if (xposedBridge.exists()) {
File optimizedDir = context.getDir("dex", Context.MODE_PRIVATE);
DexClassLoader dexClassLoader = new DexClassLoader(xposedBridge.getPath(),
optimizedDir.getPath(), null, ClassLoader.getSystemClassLoader());
Class<?> XposedBridge = dexClassLoader.loadClass("de.robv.android.xposed.XposedBridge");
Method getXposedVersion = XposedBridge.getDeclaredMethod("getXposedVersion");
if (!getXposedVersion.isAccessible()) getXposedVersion.setAccessible(true);
return (Integer) getXposedVersion.invoke(null);
}
} catch (Exception ignored) {
}
return null;
}
As far as I can tell, Xposed has always had XposedBridge.jar in /system/framework so this should work for the official releases of Xposed but could break in future releases.
I believe Snapchat uses SafetyNet, the API which also protects Android Pay and Pokemon GO.
Xposed can be checked by reflect,in class XposedHelper
public class XposedHelper {
private static final String LOGTAG = "XposedHelpers";
private static final HashMap<String, Field> fieldCache = new HashMap<>();
private static final HashMap<String, Method> methodCache = new HashMap<>();
private static final HashMap<String, Constructor<?>> constructorCache = new HashMap<>();
private static final WeakHashMap<Object, HashMap<String, Object>> additionalFields = new WeakHashMap<>();
private static final HashMap<String, ThreadLocal<AtomicInteger>> sMethodDepth = new HashMap<>();
}
check if contains your app info in these parameter.

Limiting Square Picasso's cache size to 60MB max

I am currently using Picasso to download and cache images in my app inside multiple recycler views. So far Picasso has used around 49MB cache size and i am worried that as more images come into play, this will become much higher.
I am using the default Picasso.with(context) object. Please answer the following:
1) Is there a way to restrict the Size of Picasso's cache. MemoryPolicy and NetworkPolicy set to NO_CACHE isn't an option. I need caching but upto a certain level (60MB max)
2) Is there a way in picasso to store Resized/cropped images like in Glide DiskCacheStrategy.RESULT
3) If the option is to use OKHTTP, please guide me to a good tutorial for using it to limit Picasso's cache size. (Picasso 2.5.2)
4) Since i am using a Gradle dependency of Picasso, how can i add a clear Cache function as shown here:
Clear Cache memory of Picasso
Please try this one, it does seem to work great for me:
I use it as a Singleton.
Just put 60 where DISK/CACHE size parameters are.
//Singleton Class for Picasso Downloading, Caching and Displaying Images Library
public class PicassoSingleton {
private static Picasso mInstance;
private static long mDiskCacheSize = CommonConsts.DISK_CACHE_SIZE * 1024 * 1024; //Disk Cache
private static int mMemoryCacheSize = CommonConsts.MEMORY_CACHE_SIZE * 1024 * 1024; //Memory Cache
private static OkHttpClient mOkHttpClient; //OK Http Client for downloading
private static Cache diskCache;
private static LruCache lruCache;
public static Picasso getSharedInstance(Context context) {
if (mInstance == null && context != null) {
//Create disk cache folder if does not exist
File cache = new File(context.getApplicationContext().getCacheDir(), "picasso_cache");
if (!cache.exists())
cache.mkdirs();
diskCache = new Cache(cache, mDiskCacheSize);
lruCache = new LruCache(mMemoryCacheSize);
//Create OK Http Client with retry enabled, timeout and disk cache
mOkHttpClient = new OkHttpClient();
mOkHttpClient.setConnectTimeout(CommonConsts.SECONDS_TO_OK_HTTP_TIME_OUT, TimeUnit.SECONDS);
mOkHttpClient.setRetryOnConnectionFailure(true);
mOkHttpClient.setCache(diskCache);
//For better performence in Memory use set memoryCache(Cache.NONE) in this builder (If needed)
mInstance = new Picasso.Builder(context).memoryCache(lruCache).
downloader(new OkHttpDownloader(mOkHttpClient)).
indicatorsEnabled(CommonConsts.SHOW_PICASSO_INDICATORS).build();
}
}
return mInstance;
}
public static void updatePicassoInstance() {
mInstance = null;
}
public static void clearCache() {
if(lruCache != null) {
lruCache.clear();
}
try {
if(diskCache != null) {
diskCache.evictAll();
}
} catch (IOException e) {
e.printStackTrace();
}
lruCache = null;
diskCache = null;
}
}
1) Yeah, easy: new com.squareup.picasso.LruCache(60 * 1024 * 1024). (just use your Cache instance in your Picasso instance like new Picasso.Builder(application).memoryCache(cache).build())
2) Picasso automatically uses the resize() and other methods' parameters as part of the keys for the memory cache. As for the disk cache, nope, Picasso does not touch your disk cache. The disk cache is the responsibility of the HTTP client (like OkHttp).
3) If you are talking about disk cache size: new OkHttpClient.Builder().cache(new Cache(directory, maxSize)).build(). (now you have something like new Picasso.Builder(application).memoryCache(cache).downloader(new OkHttp3Downloader(client)).build())
4) Picasso's Cache interface has a clear() method (and LruCache implements it, of course).
Ok, I did a lot of digging inside Picasso, and OKHTTP's internal working to find out how caching happens, whats the policy etc.
For people trying to use latest picasso 2.5+ and Okhttp 3+, the accepted answer WILL NOT WORK!! (My bad for not checking with the latest :( )
1) The getSharedInstance was not Thread safe, made it synchronized.
2) If you don't to do this calling everytime, do a Picasso.setSingletonInstance(thecustompicassocreatedbygetsharedinstance)
P.S. do this inside a try block so as to avoid illegalstateexception on activity reopening very quickly after a destroy that the static singleton is not destroyed. Also make sure this method gets called before any Picasso.with(context) calls
3) Looking at the code, I would advise people not to meddle with LruCache unless absolutely sure, It can very easily lead to either waste of unused RAM or if set low-> Outofmemoryexceptions.
4)It is fine if you don't even do any of this. Picasso by default tries to make a disk cache from it's inbuilt okhttpdownloader. But this might or might not work based on what picasso version you use. If it doesn't work, it uses default java URL downloader which also does some caching of its own.
5) Only main reason i see to do all this is to get the Clear Cache functionality. As we all know Picasso does not give this easily as it is protected inside the package. And most mere mortals like me use gradle to include the package leaving us out in the dust to not have cache clearing access.
Here is the code along with all the options for what i wanted. This will use Picasso 2.5.2 , Okhttp 3.4.0 and OkHttp3Downloader by jakewharton.
package com.example.project.recommendedapp;
import android.content.Context;
import android.util.Log;
import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.picasso.LruCache;
import com.squareup.picasso.Picasso;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
//Singleton Class for Picasso Downloading, Caching and Displaying Images Library
public class PicassoSingleton {
private static Picasso mInstance;
private static long mDiskCacheSize = 50*1024*1024; //Disk Cache limit 50mb
//private static int mMemoryCacheSize = 50*1024*1024; //Memory Cache 50mb, not currently using this. Using default implementation
private static OkHttpClient mOkHttp3Client; //OK Http Client for downloading
private static OkHttp3Downloader okHttp3Downloader;
private static Cache diskCache;
private static LruCache lruCache;//not using it currently
public static synchronized Picasso getSharedInstance(Context context)
{
if(mInstance == null) {
if (context != null) {
//Create disk cache folder if does not exist
File cache = new File(context.getApplicationContext().getCacheDir(), "picasso_cache");
if (!cache.exists()) {
cache.mkdirs();
}
diskCache = new Cache(cache, mDiskCacheSize);
//lruCache = new LruCache(mMemoryCacheSize);//not going to be using it, using default memory cache currently
lruCache = new LruCache(context); // This is the default lrucache for picasso-> calculates and sets memory cache by itself
//Create OK Http Client with retry enabled, timeout and disk cache
mOkHttp3Client = new OkHttpClient.Builder().cache(diskCache).connectTimeout(6000, TimeUnit.SECONDS).build(); //100 min cache timeout
//For better performence in Memory use set memoryCache(Cache.NONE) in this builder (If needed)
mInstance = new Picasso.Builder(context).memoryCache(lruCache).downloader(new OkHttp3Downloader(mOkHttp3Client)).indicatorsEnabled(true).build();
}
}
return mInstance;
}
public static void deletePicassoInstance()
{
mInstance = null;
}
public static void clearLRUCache()
{
if(lruCache!=null) {
lruCache.clear();
Log.d("FragmentCreate","clearing LRU cache");
}
lruCache = null;
}
public static void clearDiskCache(){
try {
if(diskCache!=null) {
diskCache.evictAll();
}
} catch (IOException e) {
e.printStackTrace();
}
diskCache = null;
}
}

Face Recognition on Android

I'm trying to develop a Face Recognition app on Android and since I don't want to use NDK on the project (simply don't have the time to switch), I'm sticking to develop the whole app with Java and therefor I'm having some problems :
It seems the Contrib Module isn't included in OpenCV 2.4.2 . is there anyway to use it in the project ?
I tried using JavaCV to use the Contrib Module's "FaceRecognizer" class. there are two classes available called "FaceRecognizer" & "FaceRecognizerPtr". does anybody know what the difference between these two is ?
The classes mentioned above have a method called "Train" which (In C++) receives two Vectors of types "Mat & Integer" ( model->train(images,labels) & train(Vector<mat> theImages, Vector<int> theLabels) . I tried passing them ArrayList<mat> & ArrayList<integer> and Vectors in Java but it seems that the method explicitly accepts the "CvArr" Data type which I'm not sure how to acquire... Here is the error :
The method train(opencv_core.CvArr, opencv_core.CvArr) in the type
opencv_contrib.FaceRecognizer is not applicable for the arguments
(ArrayList, ArrayList)
Does anyone know how to change my ArrayList to CvArr ?!
This is my first post and I wasn't sure whether to ask all three questions in one post or in three posts so sorry for any inconveniences... If you need any other Information about the project, feel free to ask.
Update
The following article was written by Petter Christian Bjelland, so all credit is his. I am posting it here, because his blog seems to be in Maintenance mode at the moment, but I think it is worth sharing.
Doing face recognition with JavaCV (from http://pcbje.com)
I couldn’t find any tutorial on how to perform face recognition using OpenCV and Java, so I decided to share a viable solution here. The solution is very inefficient in its current form as the training model is built at each run, however it shows what’s needed to make it work.
The class below takes two arguments: The path to the directory containing the training faces and the path to the image you want to classify. Not that all images has to be of the same size and that the faces already has to be cropped out of their original images (Take a look here if you haven’t done the face detection yet).
For the simplicity of this post, the class also requires that the training images have filename format: <label>-rest_of_filename.png. For example:
1-jon_doe_1.png
1-jon_doe_2.png
2-jane_doe_1.png
2-jane_doe_2.png
... and so on.
The code:
import com.googlecode.javacv.cpp.opencv_core;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_contrib.*;
import java.io.File;
import java.io.FilenameFilter;
public class OpenCVFaceRecognizer {
public static void main(String[] args) {
String trainingDir = args[0];
IplImage testImage = cvLoadImage(args[1]);
File root = new File(trainingDir);
FilenameFilter pngFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".png");
}
};
File[] imageFiles = root.listFiles(pngFilter);
MatVector images = new MatVector(imageFiles.length);
int[] labels = new int[imageFiles.length];
int counter = 0;
int label;
IplImage img;
IplImage grayImg;
for (File image : imageFiles) {
// Get image and label:
img = cvLoadImage(image.getAbsolutePath());
label = Integer.parseInt(image.getName().split("\\-")[0]);
// Convert image to grayscale:
grayImg = IplImage.create(img.width(), img.height(), IPL_DEPTH_8U, 1);
cvCvtColor(img, grayImg, CV_BGR2GRAY);
// Append it in the image list:
images.put(counter, grayImg);
// And in the labels list:
labels[counter] = label;
// Increase counter for next image:
counter++;
}
FaceRecognizer faceRecognizer = createFisherFaceRecognizer();
// FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
// FaceRecognizer faceRecognizer = createLBPHFaceRecognizer()
faceRecognizer.train(images, labels);
// Load the test image:
IplImage greyTestImage = IplImage.create(testImage.width(), testImage.height(), IPL_DEPTH_8U, 1);
cvCvtColor(testImage, greyTestImage, CV_BGR2GRAY);
// And get a prediction:
int predictedLabel = faceRecognizer.predict(greyTestImage);
System.out.println("Predicted label: " + predictedLabel);
}
}
The class requires the OpenCV Java interface. If you’re using Maven, you can retrieve the required libraries with the following pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pcbje</groupId>
<artifactId>opencvfacerecognizer</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>opencvfacerecognizer</name>
<url>http://pcbje.com</url>
<dependencies>
<dependency>
<groupId>com.googlecode.javacv</groupId>
<artifactId>javacv</artifactId>
<version>0.3</version>
</dependency>
<!-- For Linux x64 environments -->
<dependency>
<groupId>com.googlecode.javacv</groupId>
<artifactId>javacv</artifactId>
<classifier>linux-x86_64</classifier>
<version>0.3</version>
</dependency>
<!-- For OSX environments -->
<dependency>
<groupId>com.googlecode.javacv</groupId>
<artifactId>javacv</artifactId>
<classifier>macosx-x86_64</classifier>
<version>0.3</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>javacv</id>
<name>JavaCV</name>
<url>http://maven2.javacv.googlecode.com/git/</url>
</repository>
</repositories>
</project>
Original Post
Quoting from my reply on http://answers.opencv.org/question/865/the-contrib-module-problem.
Without ever having used javacv, let's see how far we can get by just looking at the interfaces! The project is on googlecode, which makes it easy to browse the code: http://code.google.com/p/javacv.
First have a look at how cv::FaceRecognizer has been wrapped (opencv_contrib.java, line 845 at time of writing this):
#Namespace("cv") public static class FaceRecognizer extends Algorithm {
static { Loader.load(); }
public FaceRecognizer() { }
public FaceRecognizer(Pointer p) { super(p); }
public /*abstract*/ native void train(#ByRef MatVector src, #Adapter("ArrayAdapter") CvArr labels);
public /*abstract*/ native int predict(#Adapter("ArrayAdapter") CvArr src);
public /*abstract*/ native void predict(#Adapter("ArrayAdapter") CvArr src, #ByRef int[] label, #ByRef double[] dist);
public native void save(String filename);
public native void load(String filename);
public native void save(#Adapter("FileStorageAdapter") CvFileStorage fs);
public native void load(#Adapter("FileStorageAdapter") CvFileStorage fs);
}
Aha, so you need to pass a MatVector for the images! You can pass the labels in a CvArr (one row or one column). The MatVector is defined in opencv_core, line 4629 (at time of writing this) and it looks like this:
public static class MatVector extends Pointer {
static { load(); }
public MatVector() { allocate(); }
public MatVector(long n) { allocate(n); }
public MatVector(Pointer p) { super(p); }
private native void allocate();
private native void allocate(#Cast("size_t") long n);
public native long size();
public native void resize(#Cast("size_t") long n);
#Index #ValueGetter public native #Adapter("MatAdapter") CvMat getCvMat(#Cast("size_t") long i);
#Index #ValueGetter public native #Adapter("MatAdapter") CvMatND getCvMatND(#Cast("size_t") long i);
#Index #ValueGetter public native #Adapter("MatAdapter") IplImage getIplImage(#Cast("size_t") long i);
#Index #ValueSetter public native MatVector put(#Cast("size_t") long i, #Adapter("MatAdapter") CvArr value);
}
Again just by looking at the code, I guess it can be used like this:
int numberOfImages = 10;
// Allocate some memory:
MatVector images = new MatVector(numberOfImages);
// Then fill the MatVector, you probably want to do something useful instead:
for(int idx = 0; idx < numberOfImages; idx++){
// Load an image:
CvArr image = cvLoadImage("/path/to/your/image");
// And put it into the MatVector:
images.put(idx, image);
}
You probably want to write yourself a method that does the conversion from a Java ArrayList to a MatVector (if such a function does not exist in javacv yet).
Now to your second question. FaceRecognizer is the equivalent to cv::FaceRecognizer. The native OpenCV C++ classes return a cv::Ptr<cv::FaceRecognizer>, which is a (Smart) Pointer to a cv::FaceRecognizer. This has to be wrapped as well. See a pattern here?
The interface of FaceRecognizerPtr now looks like this:
#Name("cv::Ptr<cv::FaceRecognizer>")
public static class FaceRecognizerPtr extends Pointer {
static { load(); }
public FaceRecognizerPtr() { allocate(); }
public FaceRecognizerPtr(Pointer p) { super(p); }
private native void allocate();
public native FaceRecognizer get();
public native FaceRecognizerPtr put(FaceRecognizer value);
}
So you can either get a FaceRecognizer from this class or put a FaceRecognizer into. You should only be concerned about the get(), as the Pointer is filled by the method creating the concrete FaceRecognizer algorithm:
#Namespace("cv") public static native #ByVal FaceRecognizerPtr createEigenFaceRecognizer(int num_components/*=0*/, double threshold/*=DBL_MAX*/);
#Namespace("cv") public static native #ByVal FaceRecognizerPtr createFisherFaceRecognizer(int num_components/*=0*/, double threshold/*=DBL_MAX*/);
#Namespace("cv") public static native #ByVal FaceRecognizerPtr createLBPHFaceRecognizer(int radius/*=1*/,
int neighbors/*=8*/, int grid_x/*=8*/, int grid_y/*=8*/, double threshold/*=DBL_MAX*/);
So once you have got the FaceRecognizerPtr, you can do things like:
// Holds your training data and labels:
MatVector images;
CvArr labels;
// Do something with the images and labels... Probably fill them?
// ...
// Then get a Pointer to a FaceRecognizer (FaceRecognizerPtr).
// Java doesn't have default parameters, so you have to add some yourself,
// if you pass 0 as num_components to the EigenFaceRecognizer, the number of
// components is determined by the data, for the threshold use the maximum possible
// value if you don't want one. I don't know the constant in Java:
FaceRecognizerPtr model = createEigenFaceRecognizer(0, 10000);
// Then train it. See how I call get(), to get the FaceRecognizer inside the FaceRecognizerPtr:
model.get().train(images, labels);
This learns you an Eigenfaces model. And that's it!
I made an android app for face recognition using opencv. For good recognition you need a better detection, you can check it out from: https://github.com/yaylas/AndroidFaceRecognizer
I hope it helps.

Using java.util.regex in Android apps - are there issues with this?

In an Android app I have a utility class that I use to parse strings for 2 regEx's. I compile the 2 patterns in a static initializer so they only get compiled once, then activities can use the parsing methods statically.
This works fine except that the first time the class is accessed and loaded, and the static initializer compiles the pattern, the UI hangs for close to a MINUTE while it compiles the pattern! After the first time, it flies on all subsequent calls to parseString().
My regEx that I am using is rather large - 847 characters, but in a normal java webapp this is lightning fast. I am testing this so far only in the emulator with a 1.5 AVD.
Could this just be an emulator issue or is there some other reason that this pattern is taking so long to compile?
private static final String exp1 = "(insertratherlong---847character--regexhere)";
private static Pattern regex1 = null;
private static final String newLineAndTagsExp = "[<>\\s]";
private static Pattern regexNewLineAndTags = null;
static {
regex1 = Pattern.compile(exp1, Pattern.CASE_INSENSITIVE);
regexNewLineAndTags = Pattern.compile(newLineAndTagsExp);
}
public static String parseString(CharSequence inputStr) {
String replacementStr = "replaceMentText";
String resultString = "none";
try {
Matcher regexMatcher = regex1.matcher(inputStr);
try {
resultString = regexMatcher.replaceAll(replacementStr);
} catch (IllegalArgumentException ex) {
} catch (IndexOutOfBoundsException ex) {
}
} catch (PatternSyntaxException ex) {
}
return resultString;
}
please file a reproduceable test case at http://code.google.com/p/android/issues/entry and i'll have a look. note that i will need a regular expression that reproduces the problem. (our regular expressions are implemented by ICU4C, so the compilation actually happens in native code and this may end up being an ICU bug, but if you file an Android bug i'll worry about upstream.)
If you launched with debugging you can expect it to be about twice as slow as a regular launch. However a minute does seem extraordinary. Some things to suggest, i. look at the console output to see if warnings are being spat out, ii. when it is doing the compile, in the debugger press 'pause' and just see what it is doing. There are ways to get the source, but even so just looking at the call stack may reveal something.

Categories

Resources