Android NDK - try catch with NoMemoryError - android

I have block of code, which in Android NDK allocates huge ammounts of memory. Last what I need is to use try - catch block for possibility, there might be NoMemoryError. Do you know how to write it in native SDK?
I need to implement same functionality as this:
for(int i=1;i<50;i++){
try{
int[] mega =new int[i*1024*1024];//1MB
}catch (OutOfMemoryError e) {
usedMemory= (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/new Float(1048576.0);
usedText=usedMemory+" MB";
tw.setText(usedText);
break;
}
}

In your JNI function you can throw a java exception using the follow snippet. When compiling the native code make sure RTTI and exceptions are enabled.
try {
int *mega = new int[1024 * 1024];
} catch (std:: bad_alloc &e) {
jclass clazz = jenv->FindClass("java/lang/OutOfMemoryError");
jenv->ThrowNew(clazz, e.what());
}
In Java you can simply catch the OutOfMemoryError.
try {
// Make JNI call
} catch (OutOfMemoryError e) {
//handle error
}

Android is not very friendly to C++ exceptions (you must link with a special version of the C++ library provided by Android to have exceptions). Maybe you should use malloc() and check its return value to see if memory allocation was OK?

If you trigger an exception/error in your native code you should be able to catch it. However, I would assume that allocating a big chunk of unmanaged memory using malloc or similar will not trigger an error but kill you app the hard way. If you create the same big java array as in your java code instead, however, the java method you call to create the array will fail and create an exception. As exception handling in JNI is very different you have to check for exceptions in your native code manually using something like:
exc = (*env)->ExceptionOccurred(env);
if (exc) ...

Related

How to handle different kinds of errors in Retrofit Rx onError without ugly instanceof

I would like to know your ways to handle different kinds of errors (like http exceptions, no internet connection exceptions etc) in retrofit Rx onError without using instanceof like it's proposed here: How to handle network errors in Retrofit 2 with RxJava or here: Handle errors in Retrofit 2 RX
In kotlin I will simply make some extension functions for each kind of throwable to do whatever I want.
But I am forced to use Java in the project. Any nice suggestions?
is the approach to build some kind of error handler like this:
public interface ErrorHandler {
void handleError(Exception e);
void handleError(HttpException e);
void handleError(NullPointerException npe);
}
good? I know it is not because every time i need to handle another specific error I am forced to change interface, so it is violation of Open Close Principle. But I can't figure out any solution .
cheers
Wojtek
The compiler determines which method to call, rather than the VM. So the class you've described won't solve the problem unless you check instanceof first and cast the paramter to the correct type. Otherwise you're going to get handleError(Exception e) every time.
But I wanted to create an answer not for that reason, but to argue that having only one error handler is actually preferable in many cases, not a liability. Oftentimes in java we end up in awful situations like this:
catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("No such algorithm: RSA?", e);
}
catch (NoSuchProviderException e) {
throw new IllegalStateException("No such provider: " + ANDROID_KEYSTORE_ID, e);
}
catch (InvalidAlgorithmParameterException e) {
throw new IllegalStateException("Bug setting up encryption key for user credentials: ", e);
}
catch (KeyStoreException e) {
throw new IllegalStateException("Bug setting up encryption key for user credentials: ", e);
}
catch (IOException e) {
Log.w(TAG, "Exception setting up keystore for user creds. They won't be stored.", e);
}
catch (CertificateException e) {
Log.w(TAG, "Exception setting up keystore for user creds. They won't be stored.", e);
}
Having only one error handler gives us the ability to lump many types of exceptions together. You can see in this code, there are exceptions that should never be thrown, exceptions that can really only be the result of a bug in the code, and legitimate exceptional states that we need to handle. I find this messy, and would prefer to say:
if (e instanceof NoSuchAlgorithmException || e instanceof NoSuchProviderException) {
Log.wtf(TAG, "What the heck is this?", e);
throw new IllegalStateException("This is some kind of weird bug", e);
}
else if (e instanceof IOException || e instanceof CertificateException) {
// This can happen sometimes, track event in analytics and perhaps
// try some alternative means of credential storage.
}
else {
// At least here the app won't crash if some unexpected exception occurs,
// since we're trapping everything.
}
I don't think it's such a bad thing to be able to lump unexpected failures together and handle them in a more user friendly way than crashing the app. Even if it's just a bug, better to track it in your analytics framework behind the scenes than bomb the user out of the app. So many crashes in Android apps are actually completely recoverable, but we don't go around catching Throwable in every try/catch statement because it's a lot of extra code.
The proper OOP way to avoid chained ifs or catches is polymorphism. You can define several custom exception classes exposing common interface that is enough for a single handler to process.
Suppose you need to divide errors in two groups: recoverable and not recoverable. Then your base exception class (or interface) shall have abstract method isRecoverable() that you override in each subclass. Then there will be only one if in your handler: if (e.isRecoverable()) { ... } else { ... }.
The downside is that you have to wrap all standard exceptions into your custom ones at places where they are thrown (you have to catch them).
The right choice will greatly depend on your task, though.

LibGDX : Android Game Security

I am developing game using LibGDX framework . I want to know how to make the game more secure . For example a user with rooted android device can change save .xml file so the game will be hacked , or he/she can use GameKiller or a program like that and change game runtime values (money ,exp etc.). So how can I prevent those?
And the same thing for desktop version , save file is not hidden and the player can find that file on PC too . And can use CheatEngine or other program for hacking and again change runtime values.
If you are not storing private/important data but only want to make it hard to hack your game (for example by changing xml with levels of your game) you can implement encryption basen on GWT Crypto library
The way you are initializing encryptor is:
//this will be used for encrypting and decrypting strings
private TripleDesCipher encryptor;
...
//creating key for encryptor
TripleDesKeyGenerator generator = new TripleDesKeyGenerator();
byte[] key = generator.decodeKey("04578a8f0be3a7109d9e5e86839e3bc41654927034df92ec"); //you can pass your own string here
//initializing encryptor with generated key
encryptor = new TripleDesCipher();
encryptor.setKey(key);
...
And way of using it:
private String encryptString(String string)
{
try
{
string = encryptor.encrypt( string );
}
catch (DataLengthException e1)
{
e1.printStackTrace();
}
catch (IllegalStateException e1)
{
e1.printStackTrace();
}
catch (InvalidCipherTextException e1)
{
e1.printStackTrace();
}
return string;
}
private String decryptString(String string)
{
try
{
string = encryptor.decrypt(string);
}
catch (DataLengthException e)
{
e.printStackTrace();
} catch (IllegalStateException e)
{
e.printStackTrace();
} catch (InvalidCipherTextException e)
{
e.printStackTrace();
}
return string;
}
I also recommend you not to use XMLs but JSONs - they are more convenient and weights less. Read how to handle it here
Remember that generally client-side encryption is not very good idea and always can be hacked in some way - but I'm pretty sure that if it is not about money noone will think it worth.
If you are interested in more advanced way of keeping your data save the best idea would be sending all data by SSL and save it in some well-guard server - although I'm not very sure if Libgdx has any good SSL mechanism and don't know 3rd part libraries that I could recommend.
The example of service to keep files can be Shephertz (I was using their nice AppWarp and going to implement this one in my app also).
You can use those for runtime
Twin variables
Twin for a cheatengine and gamekiller
int health=15;
int twinhealth=15;
if(HPtaken())
{
health+=10;//those twins will always change together
twinhealth+=10;
}
if(health!=twinhealth)//if they are different this means there is hack attempt
{
//punishment for hacker
}
Crypted variables
Actually its not a crypt its just little change on variables so hacker cant change easly via gamekiller or cheatengine.
int health=15*7;
int twinhealth=15*7;
if(HPtaken())
{
health+=10*7;//those twins will always change together
twinhealth+=10*7;
}
drawhealth( health/7 );// So hacker going to see and search wrong value on cheatengine
Crypted twin variables :D
Hacker ban freeze and change both twin with a same value. So at least one of the twins will be crypted.
int health=15;
int twinhealth=15*5;
if(HPtaken())
{
health+=10;//those twins will always change together
twinhealth+=10*5;
}
if(health!=twinhealth*5)//if they are different this means there is hack attempt
{
//punishment for hacker
}
Of course hacker can decompile apk and hack your game but it makes little bit harder to hack game. By the way you can use random variables for editing variables.
You can apply to xml or preferences those but you can use little bit complicated crypt because speed not an issue since you only import/export few times.

A new error I never seen before in Android. Is there any Solution?

02-07 10:49:45.558: E/dalvikvm-gc(7184): Could not create 2617344-byte ashmem mark stack: Too many open files
While I was playing the game and after some time the game forced closed showing the above error in Log Cat. Is there any solution for this?? and what could be its cause??
The cause is that your code is not closing files and the system is running out of file handles. You should always use files using a coding pattern that ensures that all streams are closed when no longer needed. Here's a typical pattern:
InputStream is = null;
try {
is = new FileInputStream(myFile);
// read stuff from is
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Log.w(LOG_TAG, "Exception raised when closing file", e);
}
}
}
The outer try could also have a catch clause. The reason for the try/catch in the finally clause is to prevent an exception in closing the file from suppressing any exception raised in the outer try block.
Writing to files tends to be less of a problem because programmers usually take care to close the file to ensure that the data reaches the file. However, a similar pattern should be followed there: never let an exception prevent the closing of a file.

Catch all exceptions and send them by e-mail

In my app I want to catch all types of exceptions and send reports by e-mail. For that I'm using global try catch block. But now I need to recognize exception by type. How can I do it?
try{
...
}
catch (Exception e){
//Here I need to recognize exception by type
send(Error);
}
Why you don't simple send the whole stacktrace?
send(e.getStackTrace())
It not only contains the Exception type but also where (file, class, line) it occurred.
Additionally, you can also simply use the toString() method.
See the java doc for further information
Instead of rolling your own error logging and reporting mechninism I strongly recommend you use ACRA Its free, open source, and supports sending error logs to email. I have used it for quite some time and it is very good.
This will give you all sorts of information such as phone make, model, resolution, free memory, as well as a full stack trace of the error. Its by far the easiest way to get quality error reporting into an Android app.
The best part is it takes all of about 5 minutes to get setup and integrated.
e.getClass() // will give you Class object
e.getClass().getName() // will give you class name
However if you know the class names already you can use
if(e instanceof A)
{
// some processing
}
else if(e instanceof B)
{
//some processing
}
else
{
//
}

Add statements for higher version?

I am using 1.6 i.e. API 4 to build my application. There are couple of commands that are supported by higher versions. I want to write those commands and make application more compatible for higher versons. Like, I use Tabs. I want to use setLeftStripDrawable and setRightStripDrawable, but they are supported by API 8.
I write something like :
// I want these lines to come into affect only if the device SDK is greater than 7 as SDK of below 7, doesn't support these methods.
if (android.os.Build.VERSION.SDK_INT > 7) {
tw.setLeftStripDrawable(R.drawable.tab_selected_bar_left_v4); // TabWidget
}
EDIT : I want to set setLeftStripDrawable to the tabs used in my app. In my manifest I have uses-sdk android:minSdkVersion="4". If I write the lines as above and compile it in 2.3, it compiles successfully. When I run in 1.6 I get "java.lang.VerifyError". If I remove those liens and again run in 1.6, it works properly.
What should I do to execute those lines only if the device SDK api is > 7, and if it is less than that then those lines should not come under any affect ?
Any clue ?
if (Build.VERSION.SDK_INT > 7) {
...
}
I think you should use something like this. I did this by heart, so there might be some errors.
try {
Method twMethod = TabWidget.class.getMethod("setLeftStripDrawable", new Class[] { int.class });
twMethod.invoke(tw, R.drawable.yourdrawable);
} catch (NoSuchMethodException e) {
/* not supported */
} catch (IllegalArgumentException e) {
/* wrong class provided */
} catch (IllegalAccessException e) {
/* Java access control has denied access */
} catch (InvocationTargetException e) {
/* method has thrown an exception */
}
You can try looking at Android Reflection. I have not used it yet myself, but as far as i understand, you can test for classes and methods that you know the name of. Then you can instantiate and use them.
You can read some of the basics here: http://www.tutorialbin.com/tutorials/85977/java-for-android-developers-reflection-basics
Here's some sample Android code, using reflection, that does something similar. It calls the getRotation() method from the Display class; the method only exists in SDK 8+. I've used it in one of my apps and it works:
//I want to run this: displayrotation = getWindowManager().getDefaultDisplay().getRotation();
//but the getRotation() method only exists in SDK 8+, so I have to call it in a sly way, using Java "reflection"
try{
Method m = Display.class.getMethod("getRotation", (Class[]) null);//grab the getRotation() method if it exists
//second argument above is an array containing input Class types for the method. In this case it takes no inputs.
displayrotation = (Integer) m.invoke(getWindowManager().getDefaultDisplay(),(Object[]) null);
//again, second argument is an array of inputs, in this case empty
}catch(Exception e){//if method doesn't exist, take appropriate alternate actions
Log.w("getRotation","old OS version => Assuming 90 degrees rotation");
displayrotation = Surface.ROTATION_90;
}

Categories

Resources