I faced a suspicious problem when I tried to update my Android App to work on 4.2.1, Nexus 7. I'm using my own .so library, which inclusion was working fine on Android version 4.1, before I updated. Now I get all sorts of problems.
I compared the logs when deploying on an Android device running 3.2.1 and my Nexus 7 running 4.2.1. The library is being placed in two different locations, which might be causing my problems.
ANDROID 3.2.1:
Trying to load lib /data/data/com.my.app/lib/lib_my_app_jni.so 0x407e8218
Added shared lib /data/data/com.my.app/lib/lib_my_app_jni.so 0x407e8218
ANDROID 4.2.1 (Nexus 7):
Trying to load lib /data/app-lib/com.my.app-1/lib_my_app_api_jni.so 0x4257b6c8
Added shared lib /data/app-lib/com.my.app-1/lib_my_app_api_jni.so 0x4257b6c8
Why is it all of the sudden placed in the mysteries app-lib dir? How do I force it back? And where is this documented?
Thanks...
From Android 4.2, multi-user feature added in android frameworks.
And several directory locations are changed, but API is not changed such as Context.get???Dir() or Context.get???Path(). (just return value is changed)
Also android platform make symbolic link for legacy.
These changes are not documented.
I'm going to answer my own question, because we ended up implementing our library differently then originally intended.
The problem was that we were copying over access certificates and more, to the directory that the library was in. This approach worked fine on older Android versions, where that was located in the data/data/package/. But on newer Android versions (data/app-lib/package/) that location is read-only.
What we did was to move the location, simple. Thanks for the input.
Related
I'm developing an Android app which gets signed by the platform certificate.
For testing purposes I'm using the Android Emulator with x86_64 AOSP image, API Level 27, Android 8.1.
The app wants to use a function that has been declared as hidden with the #hide annotation. As expected Android Studio 3.0 can't resolve the symbol.
I could use reflection, but since my app has the rights to use the internal functions, I try to avoid reflection.
How can I make Android Studio aware of the hidden functions ?
I searched on SO and google, but couldn't find a suitable solution, only old ones (two years and older) that doesn't work (anymore).
oat2dex method that doesn't work
You need to be building AOSP in order to force reveal these methods to Android Studio. You can remove the hide annotation in the .java files under framework, and then compile the sdk using the following lines,
lunch sdk-eng
make update-api
make sdk
Then resolve the lint errors as they come, the errors themselves will tell you ways in which you can resolve them. Once this is done, copy the generated sdk folder to the ".Android/sdk/platforms" directory and re-open Android Studio.
EDIT: Just adding that such apps based on a re-compiled sdk would not work on a normal sdk since those functions are not recognized by the normal sdk. So in a controlled environment, you can make it work.
My app targets Android 4.4 and up. But I have SDKs from like 14-25 installed via the Studio SDK Manager. I don't use the emulator except on rare occasions - but when I do its typically for 4.4 & 5x. But collectively Android Studio is taking up over 100Gb of storage on my system...I need to reduce its size (big time)
What can I delete that allows me to still target 4.4 and everything newer?
This question has been asked a multitude of times but everything I researched did not provide a clear answer.
If I delete 14-24, and build my app with just SDK 25, can my app still support Android 4.4? Or do I need to hold on to specific SDKs so that my app will still support all Android versions 4.4 and higher? Please be specific, too many vague answers out there.
My app is a cordova/ionic app - many plugins references specific versions of SDKs - typically based on when the plugin was last updated. But quite often these plugins are tested with SDK 22, or SDK 21 (mainly because the author has never bothered to update/maintain the plugin - but it still works) - will those plugins still work if SDKs 14-24 are deleted and only SDK 25 is installed?
As mentioned, I occasionally need the emulator for specific system-images; in lieu of question #1 - if I want to try spin up Android 4.4 emulator do I also need to keep specific SDKs to support those system-images.
Using the Android Studio SDK Manager - does removing specific SDKs via the manager also delete things from my hard drive? I would think it would, but I read some other blogs where people were manually having to delete things.
the Build procedure depends of BuildTools and Android SDK. If you set "minSdkVersion: 10" and "targetSdkVersion: 27" then YOU SHOULD manage all code differences between all versions. There are two possibilities: (A) older method/class is not more available on newer SDK: then the bulld procedure will fail because you cannot call/use them directly but only via Reflection (B) newer method/class is not present in the older SDK: then the build procedure ends fine but your App will crash when THAT method/class is used if you don't manage that specific case using "if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.xxxx)..."
it depends of what kind of plugin they are. Are they AAR file? Are they an editable project that you could join/add to yours? are them external libraries? AAR files and .SO libraries are already compiled so they doesn't need any other/external file or development tool.
Emulator runs using its own "System OS" files, so all the development stuff is unuseful for it. You can run an Emulator even without having never installed a development tool (Android Studio or other things)
Removing items from the Manager should remove even its files, but in some case there could be a bug and nothing (or just partially) is deleted. But you can check your drive storage free space if it is increased.
I had tried Android studio, android eclipse, and what not, and have constantly been getting R.java file missing error ... that never used to happen with jelly beans .
Is there a way I can use the previous version compilers, as in the ones who don't include any support library for Android kitkat?
You should specify target API version to make it compatible for the specified API level.
cleaning project and rebuilding it will remove the R.java error
I'm using the latest version of ConcurrentLinkedHashMap as a cache system. It works very fine on android 4+. But when I run the app on my old HTC legend (Android 2.2) it stops with NoClassDefFoundError Exception. I didn't test it with 2.3 or 3.
As I searched the exception relates to a class that is present at compile time but absent during run time. But I don't know why it works fine on android 4 but not 2.2. Maybe it relates to android java coding style? any suggestion is appreciated.
EDIT ---------------------
I just used version 1.2 of ConcurrentLinkedHashMap instead of 1.4. It works fine. But why doesn't version 1.4 works?
EDIT 2 ------------------
The exception is thrown for an internal class of ConcurrentLinkedHashMap which is LinkedDeque. Not an external library. And By the way I compile the code against android 2.2 SDK not 4. So if if it requires any library of android 4 it must not be compiled.
Your LinkedDeque class depends on Deque which is only available on Android since API Level 9 (Android 2.3).
By the way, your class is really overkill and on Android you should use LruCache instead (included in the support library, works on Android 1.6 and above).
As I searched the exception relates to a class that is present at compile time but absent during run time. But I don't know why it works fine on android 4 but not 2.2.
You already answered that question yourself -> it does not work on 2.2 because there's no library that is needed. You need to check stacktrace from crash to see what lib exactly it is missing.
I have built an Android app that worked fine on Android 2.3.* and 4.0.*. However, after upgrading my device to Jelly Bean (4.1.1), I found my app does not work properly (crashes, ANRs, etc.) any more.
As a temporary workaround, I am wondering if it is possible to pack an earlier version (say Android 2.3) of the Android framework JAR into my APK and force all my code to use classes/APIs in that JAR?
I think including the JAR in my APK should be easier. But I have no idea how I could force my code to use classes/APIs in the JAR during run-time.
I know it is not a decent fix (hacking, package size, legal issue, etc.) even it will work. But I am just curious whether it is feasible.
Any suggestions or hints would be appreciated!
(Edit)
I have tried the following:
Extracted the /system/framework/framework.odex from an Android 2.3 ROM;
Deodexed it and converted it into a JAR file (say framework.jar);
I verified framework.jar and it contains the actual framework code, not stub methods;
Put framework.jar into the libs folder of my project and built out the APK;
I verified the result APK and the android framework classes are indeed included.
However, it seems my code is still using the classes/APIs of the actual version of SDK installed in the Android device. :(
(Edit)
It seems all the framework/core classes are already pre-loaded from the device (/system/framework/framework.odex) by Zygote during system boot-up time, for performance reason. So even I have included those classes in our APK, the pre-loaded ones will still be instantiated instead.
This sounds like a dead end to me... :(
As a temporary workaround, I am wondering if it is possible to pack an earlier version (say Android 2.3) of the Android framework JAR into my APK and force all my code to use classes/APIs in that JAR?
That is not possible, sorry. What you think of as "the Android framework JAR" has no code -- it is merely stub implementations of the classes and methods exposed in the Android SDK. The real Android framework resides in the firmware, and you cannot replace it.