Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[MOSYNC-2037] Added missing exception handling to bitmap allocations …

…(this caused applications to crash badly), added improved synchronization of maWait and PostEvent (may cause future merge conflict with similar update in experimental Reload branch).
  • Loading branch information...
commit 36a4cdc9daf5b65f065db95acd017841d723a70a 1 parent 2ef2eb7
Mikael Kindborg authored
127 runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncThread.java
View
@@ -55,7 +55,6 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
@@ -289,7 +288,11 @@ public native int nativeCreateBinaryResource(
int mTextConsoleHeight;
+ /**
+ * Variables used to synchronize event posting.
+ */
private volatile boolean mIsSleeping;
+ private volatile boolean mIsEventPosted;
/**
* Ascent of text in the default console font.
@@ -340,6 +343,7 @@ public MoSyncThread(Context context, Handler handler) throws Exception
mHasDied = false;
mIsSleeping = false;
+ mIsEventPosted = false;
mMoSyncNetwork = new MoSyncNetwork(this);
mMoSyncSound = new MoSyncSound(this);
@@ -782,6 +786,7 @@ public synchronized ByteBuffer readInputStream(InputStream is) throws Exception
* @param data The data to fill the new data object with.
* @return The handle to the data if successful, <0 on error.
* If a placeholder is supplied, that value is returned on success.
+ *
* TODO: This method needs improved error checking.
*/
public int createDataObject(int placeholder, byte[] data)
@@ -833,8 +838,14 @@ void storeIfBinaryAudioResource(int soundHandle)
* @param options The bitmapFactory options
*
* @return The created Bitmap, null if it failed
+ *
+ * TODO: There is no need for this method to be synchronized.
+ * Find out why it was synchronized.
*/
- synchronized Bitmap decodeImageFromData(final byte[] data, final BitmapFactory.Options options)
+ //synchronized
+ Bitmap decodeImageFromData(
+ final byte[] data,
+ final BitmapFactory.Options options)
{
try
{
@@ -843,17 +854,31 @@ synchronized Bitmap decodeImageFromData(final byte[] data, final BitmapFactory.O
{
public void run()
{
- Bitmap bitmap = BitmapFactory.decodeByteArray(
+ // Here we can get:
+ // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
+ try
+ {
+ Bitmap bitmap = BitmapFactory.decodeByteArray(
data, 0, data.length, options);
-
- waiter.setResult(bitmap);
+ waiter.setResult(bitmap);
+ }
+ catch (OutOfMemoryError e1)
+ {
+ //Log.i("@@@", "decodeImageFromData - " + "Out of memory error : " + e1);
+ waiter.setResult(null);
+ }
+ catch (Throwable e2)
+ {
+ //Log.i("@@@", "decodeImageFromData - " + "Error : " + e2);
+ waiter.setResult(null);
+ }
}
});
return waiter.getResult();
}
catch(InterruptedException ie)
{
- Log.i("MoSync", "Couldn't decode image data.");
+ //Log.i("MoSync", "Couldn't decode image data.");
return null;
}
}
@@ -882,8 +907,15 @@ public void run()
* @param height The width of the created Bitmap
*
* @return The created Bitmap, null if it failed
+ *
+ * TODO: There is no need for this method to be synchronized.
+ * Find out why it was synchronized.
+ *
+ * TODO: Look into eliminating code duplication between
+ * createBitmap and createBitmapFromData.
*/
- synchronized Bitmap createBitmap(final int width, final int height)
+ //synchronized
+ Bitmap createBitmap(final int width, final int height)
{
try
{
@@ -892,10 +924,25 @@ synchronized Bitmap createBitmap(final int width, final int height)
{
public void run()
{
- Bitmap bitmap = Bitmap.createBitmap(
+ // Here we can get:
+ // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
+ try
+ {
+ Bitmap bitmap = Bitmap.createBitmap(
width, height, Bitmap.Config.ARGB_8888);
- waiter.setResult(bitmap);
+ waiter.setResult(bitmap);
+ }
+ catch (OutOfMemoryError e1)
+ {
+ //Log.i("@@@", "createBitmapFromData - " + "Out of memory error : " + e1);
+ waiter.setResult(null);
+ }
+ catch (Throwable e2)
+ {
+ //Log.i("@@@", "createBitmapFromData - " + "Error : " + e2);
+ waiter.setResult(null);
+ }
}
});
return waiter.getResult();
@@ -915,8 +962,15 @@ public void run()
* @param pixels The pixel data
*
* @return The created Bitmap, null if it failed
+ *
+ * TODO: There is no need for this method to be synchronized.
+ * Find out why it was synchronized.
*/
- synchronized Bitmap createBitmapFromData(final int width, final int height, final int[] pixels)
+ //synchronized
+ Bitmap createBitmapFromData(
+ final int width,
+ final int height,
+ final int[] pixels)
{
try
{
@@ -925,17 +979,32 @@ synchronized Bitmap createBitmapFromData(final int width, final int height, fina
{
public void run()
{
- Bitmap bitmap = Bitmap.createBitmap(
+ // Here we can get:
+ // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
+ try
+ {
+ Bitmap bitmap = Bitmap.createBitmap(
pixels, width, height, Bitmap.Config.ARGB_8888);
- waiter.setResult(bitmap);
+ waiter.setResult(bitmap);
+ }
+ catch (OutOfMemoryError e1)
+ {
+ //Log.i("@@@", "createBitmapFromData - " + "Out of memory error : " + e1);
+ waiter.setResult(null);
+ }
+ catch (Throwable e2)
+ {
+ //Log.i("@@@", "createBitmapFromData - " + "Error : " + e2);
+ waiter.setResult(null);
+ }
}
});
return waiter.getResult();
}
catch(InterruptedException ie)
{
- Log.i("MoSync", "Couldn't create bitmap from pixel data.");
+ //Log.i("MoSync", "Couldn't create bitmap from pixel data.");
return null;
}
}
@@ -953,11 +1022,14 @@ public void updateScreen()
*/
public void postEvent(int[] event)
{
- synchronized(mPostEventMonitor) {
+ synchronized(mPostEventMonitor)
+ {
// Add event to queue.
nativePostEvent(event);
- // Wake up thread if sleeping.
- if(mIsSleeping)
+
+ mIsEventPosted = true;
+
+ if (mIsSleeping)
{
interrupt();
}
@@ -2149,7 +2221,7 @@ int _maCreateImageRaw(int placeholder, int width, int height, ByteBuffer buffer)
Bitmap bitmap = createBitmap(width, height);
- if(null == bitmap)
+ if (null == bitmap)
{
maPanic(1, "Unable to create ");
}
@@ -2170,7 +2242,6 @@ int maCreateDrawableImage(int placeholder, int width, int height)
SYSLOG("maCreateDrawableImage");
try
{
-
Bitmap bitmap = createBitmap(width, height);
Canvas canvas = new Canvas(bitmap);
@@ -2445,7 +2516,17 @@ void maWait(int timeout)
{
SYSLOG("maWait");
- mIsSleeping = true;
+ synchronized(mPostEventMonitor)
+ {
+ if (mIsEventPosted)
+ {
+ mIsEventPosted = false;
+ return;
+ }
+
+ mIsSleeping = true;
+ }
+
try
{
if (timeout<=0)
@@ -2858,14 +2939,20 @@ boolean loadImage(int resourceIndex, int pos, int length, int binaryResource)
Bitmap bitmap = decodeImageFromData(ra, null);
+ // TODO: Remove commencted out line.
//Bitmap bitmap = BitmapFactory.decodeByteArray(ra, 0, length);
- if(bitmap != null)
+
+ if (bitmap != null)
{
SYSLOG("Bitmap was created!");
mImageResources.put(
resourceIndex, new ImageCache(null, bitmap));
+
+ // Return success.
return true;
}
+
+ // If we end up here an error occurred.
logError("loadImage - Bitmap wasn't created from Resource: "
+ resourceIndex);
return false;
Please sign in to comment.
Something went wrong with that request. Please try again.