Because there is no function malloc_trim in ndk , so I want to find a way to implement malloc_trim(0) in ndk !
A simple definition like the following should suffice:
int malloc_trim(size_t pad) { return 1; }
Better still is to see if whatever library you're compiling has a flag to disable the use of malloc_trim at all.
EDIT: According to this post, jemalloc is the default memory allocator. jemalloc uses mmap by default, not sbrk. Jemalloc automatically returns memory to the OS when certain conditions are met, so I would not bother trying to come up with a useful implementation for malloc_trim.
Related
Im building a project that needs to modify the behavior of some bionic methods (e.g getaddrinfo, __android_print). I've been able to create the hooked library both using a standalone compiler or including it directly in the Apk using Cmake. I've been able to preload the shared library using setprop wrap.com.foo.bar and LD_PRELOAD, and it is working and I get the result I want. However, I want to preload the hooked library programatically so I dont need to go through the specific steps of LD_PRELOAD (a.k.a disable SELinux, root device, setprop), every time after rebooting a device.
I tried using
// MainActivity
companion object {
System.load("/data/data/com.foo.bar/lib/libhookedmethod.so")
}
But I don't see the method being replaced.
As a reference, the hooked method is rather simple. Here's an extreme simplification:
int __android_print(varargs a) {
int realmethod(...);
realmethod = dlsym("__android_print");
doStuff();
int res = realmethod(a) ;
return res;
}
Again, compiling and using LD_PRELOAD works, but I want to achieve it without using LD_PRELOAD...
Anything helps! Thanks in advance
The LD_PRELOAD works by asking the dynamic loader to load referenced library before any other. The loader resolves references to a given symbol by searching loaded libraries in their load order.
Once a symbol is resolved to a particular library, it will not be rebound to some other library for the duration of this process.
Above explanation should make it obvious why loading libhookedmethod.so after the program is already running has no effect.
About the only way you can achieve what you want is to setenv() (if not already set) and re-exec() the current process. Something like this:
int main(int argc, char *argv[])
{
char *e = getenv("LD_PRELOAD");
if (e == NULL || /* any other checks that show LD_PRELOAD to not be as we want it */) {
setenv("LD_PRELOAD", ..., 1);
execvp(argv[0], argv);
}
// LD_PRELOAD is to our liking. Run the actual program.
...
}
The official opencv android builds do not contain the opencv_contrib modules and building them yourself is not trivial. Luckily we don't have to do the building thanks to chaoyangnz.
However, with those builds there are no JNI definitions for creating WLSDisparityFilter objects so, although the underlying ximgproc libraries are there, you can't actually create a WLS filter for filtering stereo depth maps.
How can you use WLSDisparityFilter on Android?
Thankfully, the underlying libraries are present so you can use them simply by adding the java interface.
Open the: /src/main/java/org/opencv/ximgproc/DisparityWLSFilter.java file.
Add the following method:
public DisparityWLSFilter createDisparityWLSFilter(StereoMatcher matcher_left) {
DisparityWLSFilter filter = createDisparityWLSFilter_0(matcher_left);
return filter;
}
That's it! Now you can create and use WLSDisparity filters. Note, you'll have to use the full version of the filter function. Something like this in Kotlin:
val disparityWLSFilter = createDisparityWLSFilter(stereoSGBM)
disparityWLSFilter.lambda = PrefHelper.getLambda()
disparityWLSFilter.sigmaColor = PrefHelper.getSigma()
disparityWLSFilter.filter(disparityMatLeft, leftMat,
disparityMatFiltered, disparityMatRight, Rect(0, 0,
disparityMatLeft.cols(), disparityMatLeft.rows()), rightMat)
I am only using this module from opencv_contrib, although I imagine other missing ximgproc functions and other contrib modules could be enabled in much the same way.
Hopefully this helps someone else turn chunky, pixel-y disparity maps into beautiful depth maps!
I happen unable to add LocationLayerPlugin to my Android project and cannot find any documentation to demonstrate how. Also, I can't find NavigationMapRoute inside package com.mapbox.services.android.navigation.ui.v5. Any help, please?
EDIT:
That's my build.gradle below and when typing LocationLayerPlugin, Android Studio cannot resolve it.
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:5.1.0#aar') {
transitive = true
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:2.1.3#aar') {
transitive = true
}
compile 'com.mapbox.mapboxsdk:mapbox-android-navigation:0.3.1'
For the LocationLayerPlugin you can use it with two lines of code:
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
You'll need to make sure to also call the lifecycles in the appropriate methods onStart and onStop. If you are using with navigation and want to use location snapping to the route, you will need to pass in null for the locationEngine and than use forceLocationUpdate inside onProgressChange.
A few examples are available here which show different ways to use the plugin. Documentation will be avliable soon once we release the first final version (currently just producing nightly builds).
For the NavigationMapRoute you'll need to make sure you are using the 0.4.0-snapshot of the Navigation SDK. you'll find it here com.mapbox.services.android.navigation.ui.v5.NavigationMapRoute
When I attempt to deploy my app using Eclipse it throws FileNotFoundException on my font, which I've now copied to both the assets/src and assets directory to be doubly sure.
I had this problem before, after succesfully integrating SDL_ttf into my Visual C++ build of the same app and transferring across to Eclipse for Android. Now I'm facing it again I thought I better write about it. The SDL_ttf source comes with a freetype folder already in place and referenced by android as external/freetype-2.4.12. DinoMage states I need to download this separately although he refers to freetype-2.4.11 being the latest. That's the only obvious difference from my VC build, apart from minor compiler intolerances.
I've got it working a bit now. I can sign the app (unsigned didn't work), disable USB debugging, and it will load the font and display a menu. From there it breaks, again, so I can't see how I'm supposed to debug it further. I'm sure I'll fix it somehow. But I'll also forget the obscura if I don't post here.
I don't know much about using the debugger with Android, but I can make suggestions otherwise.
Is your assets path really named "assetts"? If possible, I'm not sure how one would get Android and SDL to look there instead of "assets".
SDL and it's friend libs like SDL_ttf search for files local to the assets directory first and then search relative to the root directory. So I would expect that your "res/stubbornFont.ttf" will never load because it is in the resources "res" directory and SDL_ttf will not look there.
Maybe you can specify it relative to assets/, like "../res/stubbornFont.ttf", but I haven't tested that. It would work if you put the font in assets/ and loaded it as "stubbornFont.ttf".
I've think I've got closure on this.
It is possible to debug the app. By continuing it will trap several times trying to load one font. I think it stops eventually, I'm not sure. I've stepped through it from where it lands me at the throw stage. However single stepping from there begins from the synchronized statement, sorry it's Java but from my quick reference to What does 'synchronized' mean? I think this is a race condition
public final AssetFileDescriptor openFd(String fileName)
throws IOException {
synchronized (this) {
if (!mOpen) {
throw new RuntimeException("Assetmanager has been closed");
}
ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
if (pfd != null) {
return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
}
}
throw new FileNotFoundException("Asset file: " + fileName);//DEBUGGER traps here
}
You might be there all day single stepping that! It appears to perform all steps required of it and finally I land in:
public static ReadableByteChannel newChannel(InputStream inputStream) {
return new InputStreamChannel(inputStream);
}
No, not finally, lastly, there is
public static Context getContext() {
return mSingleton;
}
In the SDLActivity I extend.
That has a bunch of members I don't want to know about:
Luckily I discovered I can selectively "Disconnect" using a button in eclipse two along from debug/run. It has no keyboard shortcut and I'm not sure why but it will reconnect when I next trigger an exception. This is debugging as I know and love it in Android and Eclipse, still probably easier than GDB.
For arguments sake I've even replaced:
//TTF_Font *gFont = TTF_OpenFont( "res/stubbornFont.ttf", 160 );
with
TTF_Font *font=TTF_OpenFontRW(SDL_RWFromFile("res/stubbornFont.ttf", "rb"), 1, 160);//Same difference
UPDATE/EDIT
Here is the solution I was really looking for,
turning off uncaught exceptions in eclipse, it really is just that, Window->Preferences->Java->Debug and it's the very first box at the top for me.
Is there any kind of conditional compiling for Android?
I had to make my project for Android 3 (API 11) just because ExifInterface has almost no useful attributes in Android 2.3 (API 10), despite the fact that it appeared in API 5 (!!??). I don't want to restrict my app to ICS users.
Thanks!
You can check dynamically the current API version of the device and do different stuff depending on that:
if(Build.VERSION.SDK_INT < 14) {
// Crappy stuff for old devices
}
else {
// Do awesome stuff on ICS
}
But be careful that if you need to instantiate classes that are not available for all APIs then you should do it in a runnable or in a separate wrapper class, e.g:
if(Build.VERSION.SDK_INT < 14) {
// Crappy stuff for old devices
}
else {
// Do awesome stuff on ICS
new Runnable() {
new AmazingClassAvailableOnICS();
(...)
}.run();
}
import android.annotation.TargetApi;
and then use annotations:
#TargetApi(11)
public void methodUsesAPI11()
{
...
Using this trick does a very simple thing: it allows compiling some code which contains API level 11 calls (classes, methods, etc) and still set android:minSdkVersion="8" in the manifest. Nothing more, nothing else.
The rest is up to you. You must check platform version before you call methodUsesAPI11() or you handle exceptions in order to prevent app crash and perform other action on older platforms.
Checking Build.VERSION.SDK_INT or using annotations should suffice, however, this link I'd bookmarked might be relevant to your case:
http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html?m=1
You can use what they describe there to have classes that may not be compatible, but will never be loaded. It's not conditional compilation, but it may be what you need, however, it is a bit more complex.