Running apps containing large amount of code - android

Background
It seems some old Android OSs (and maybe even the newest ones) have a limitation on the amount of code each app can hold.
As I've found, the limitation is on a buffer called "LinearAlloc" .
On 2.2 or 2.3 it's about 5-8 MB , and I think it's 16 or more on others.
The problem
If you have a too large code (and apps can reach this state), you won't be able to install the app at all on older devices, getting the next error (also reported here) :
Installation error: INSTALL_FAILED_DEXOPT
Please check logcat output for more details.
Launch canceled!
What I've found
One solution is to just remove as much code and libraries as possible, but on some huge projects such a thing is very hard to do.
I've found the next links talking about how Facebook solved this, by somehow increasing the limit:
http://www.slashgear.com/how-facebook-fixed-its-gingerbread-dalvik-problem-04272478/
http://arstechnica.com/business/2013/03/how-facebook-dug-deep-within-android-to-fix-its-mobile-app/
https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920
Also, Google has posted how to solve it by loading code dynamically :
http://android-developers.blogspot.co.il/2011/07/custom-class-loading-in-dalvik.html
The question
How did Facebook do it?
Is it possible to overcome this in other ways too?
Is there any free library that increases/removes the limitation of this buffer?
What is the limitation on newer Android versions, if there is any?
How do other huge apps (and games) handle this issue? Do they put their code into C/C++?
Would loading the dex files dynamically solve this?

The limit is the total number of method references:
https://code.google.com/p/android/issues/detail?id=7147#c6
https://code.google.com/p/android/issues/detail?id=20814#c6
A middle ground between doing nothing and the multi-dex approach described in the FB/Google articles is to use a tool like ProGuard to remove references to unused code at the Java level. See:
http://proguard.sourceforge.net/
http://developer.android.com/tools/help/proguard.html

There is a new solution, made by Google:
https://plus.google.com/+IanLake/posts/JW9x4pcB1rj?utm_source=Android%20Weekly&utm_campaign=59f1f4bf4d-Android_Weekly_125&utm_medium=email&utm_term=0_4eb677ad19-59f1f4bf4d-337848877
http://developer.android.com/reference/android/support/multidex/MultiDexApplication.html
It seems all you have to do is any of the next things:
- extend from "MultiDexApplication" instead of from "Application"
- call MultiDex.install(context) in your application's attachBaseContext
But now I wonder:
Is that really it?
Does it have any issues ? Does it affect performance?
How does it work?
What should be done with ContentProvider, as it's getting called before Application gets initialized?
The post says "gives you MultiDex support on all API 4+ devices (well, until v21, where you get this natively)" . Does it mean that from v21 it will be the default behavior, or just that the class will be built in and you won't need to use the support library's class ?
Will this solution work on Eclipse too?

Related

Why does the apk abort only in the release version on Android 10?

I'm using Unity 2018.4 to make a 2D game. I am facing a strange error with native code (possibly coming from some library) only in a release version and possibly in Android 10.
I don't know how to interpret the abort message.
Abort message
The only library I used that doesn't start with Unity is libsqlite3.so extracted from the SQLite website itself. (Link here)
I also have the errors coming from Google Play by Android Vitals, but it’s just as unreadable.
Does anyone know how I can solve? My game is already in the Play Store and I am receiving some complaints.
SIGSEGV, nice. Welcome to the club of games programmers who have managed to really crash Android hard. I've got a couple of guesses, but can't say for certain. More info would be useful - is this happening to all users of your release, or just some devices or device families?
I've managed to do the same, but my crash was consistent - happened every time, not just release. I had some libGDX native objects open, then tried to change the activity before closing them. My crash looked quite like yours. Check your screen changes to make sure that you cleanly close all your objects before trying to change activities/fragments.
The fact that you mention release makes me think of ProGuard. If you have it turned on it can aggressively optimise out classes that are 'unused'. This means that if you have classes you use via reflection then they won't be compiled into the release bundle. You could try turning it off completely and making a release, to see if that makes things work again. If this is the cause, look into
-keepclasseswithmembers class [your_class_path].** {*;}
in your proguard-rules.pro.
What I was suspecting was correct, the problem was the 64x library libsqlite3.so, I didn't quite understand what might have happened, I replaced the library with one from this source.

Any way to see all the methods that don't work at once? Android Studio

I have to estimate the time it takes to update a specific application made for Android 4.4 to Android 10 and I need to see all the methods that are deprecated or not working. Is there any way to see the methods without going file by file? (I'm using Android Studio with Java)
When I build the application I only get one or two types of error at a time, when I correct them I get another one and so on.
Thanks and best regards.
P.S: How long does it take you to update something like that? I'm a junior and I'm a little lost doing this.
Here, go to Analyze -> Inspect code. After inspecting check maturity there you will have depreciated methods. (Don't forget to change minSdk)
After you will do that it give you method with a warning and you can filter it by having API not support warning

INSTALL_FAILED_DEXOPT when using GreenDao

Background
I wanted to simplify the usage of DB in an Android app.
For this, I've compared some third party libraries that create a DAO layer.
I've come up with a nice library called "GreenDao" (presentation about it here) . The website shows that it's faster than other competitors (like ORMLite) and is optimized for Android.
The problem
For some reason, on some device (usually old devices, with GB) , I get the next console error when trying to install the app:
Installation error: INSTALL_FAILED_DEXOPT
Please check logcat output for more details.
Launch canceled!
I've searched for the reason of this error, but couldn't find out how to solve it. Many complain about this error, but I can't find out why it occurs, and what can be done.
The error is quite common and known, but it's never mentioned as the result of using this library, yet when I remove the usage of this library, everything works fine...
Also note that on newer devices (like nexus 4) it installs and works just fine, and that the sample itself also works fine no matter which device I test it on.
The question
Why does it occur?
Is it possible that the structure of the classes is just too much for old devices to load, since we use other libraries ?
Could it be that I've reached the limit of code that is supported by android apps?
The jar file itself takes just 87KB ...
How can I solve this?
Ok, I've found the problem and the solution:
It has nothing to do with GreenDao.
It's because the app uses too many jars, so maybe Android has a limitation of code.
The solution is to either delete un-needed jar files or delete a lot of code.

Boost text_oarchive constructor crashes on Android, not windows

I'm trying to port a game to Android, and I've been using boost for the saving / loading behaviour. The App now crashes when the save code is called. The crash occurs while trying to make text_oarchives, as with the following sample code:
void OHRMapArchiver::saveMap()
{
// copy some boost-incompatible data structures into ivar vectors
mapInstance->preSave();
CCLog("preSave");
std::ofstream outStream(MAP_SAVE_FILE);
CCLog("creating archive");
boost::archive::text_oarchive outputArchive(outStream);
CCLog("Outputting archive");
outputArchive << mapInstance;
// destroy all that stuff copied during pre-save
mapInstance->tileLoader.erase(mapInstance->tileLoader.begin(), mapInstance->tileLoader.end());
}
I sure could use some advice on why this might not be the case. I've given up on being able to debug on device, but the specific error I'm getting when
boost::archive::text_oarchive outputArchive(outStream);
is called is "Fatal signal 11 (SIGSEGV) at 0xdead (code=1), thread 1969 (Thread-112)". So segfault, but I can't imagine why, when as far as I know, it's only creating a wrapper around an ostream.
Other helpful clues... hm, I know I can create objects that implement serialize( Archive &ar, int version ), although I can't say for sure any objects have called it successfully yet. Possible linkage problems?
Also, file access permissions are enabled for App. At least, "uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" " has been added to the manifest, and I can make and output files using std::ostream.write without crash. Also, as title implies, the win32 version works perfectly, outputting data as expected and reading back in without crash.
Using crystaX ndk r7, on device using Jelly Bean.
Any thoughts on why this crashes on Android?
EDIT: Update to this. According to boost aficionados, I was wrong in my assumption that Boost is incompatible with the most recent official release of the Android NDK. If user config files are properly defined, boost ought to compile just fine against the latest.
Instead, I hear rumblings that boost iostreams routinely crash with the Kit.
This really isn't an answer; I haven't found / can't find one of those. All I can recommend is that you simply not try to do what I am doing. At least, not with android NDK r8d.
After looking into ways to properly configure Boost to build without wchar support, which the NDK somewhat half-asses, code that works on windows crashes somewhere within the serialization / archive library in boost. I don't know where.
So yes, the answer is 'give up, preferably before wasting four months tracking solutions'.

Why start excluding my own application's resources when this wasn't needed before?

I was recently hit with a puzzling problem with no explanation that I somehow managed to solve.
The solution itself poses a problem for me because I don't understand it: It forces me to direct Proguard to ignore all warnings regarding my own application's package in its entirety.
-dontwarn com.bta.**
Aside from the troubling issue of having to ignore warnings about the most error-prone code in my development (most frequently changing code), I am puzzled by two questions:
Why did this need suddenly showed up? (I never needed to do this
before.)
Why isn't this needed in other projects/applications that I
develop?
I believe some new code or library that I introduced caused this (AdMob?) but what is the explanation for this? Why would a third party library force me to turn off warnings about my own application's resources?
What are the side effects of turning off warnings about my own application package entirely (like I did)?
Answering my own question:
After wasting way too much time on debugging the very tools that are supposed to save me time, I discovered the source of the problem. It's a bug in the Android SDK tools. It is documented as have been solved in r17, but I am using the latest of today (June 18 2012) and it hasn't been solved! (see comment 24). Comment 25 also describes the workaround that allows me now to proceed with my actual development.
Bugs are fact of life in complex systems. But the fact that neither Proguard nor the build tools that feed input to Proguard could provide any helpful error message (in fact they did exactly the opposite), suggests something is broken in the "methodology" of the Android development tools recommended by Google.

Categories

Resources