Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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
@@ -55,7 +55,6 @@
55 55 import java.io.FileInputStream;
56 56 import java.io.FileNotFoundException;
57 57 import java.io.FileOutputStream;
58   -import java.io.IOException;
59 58 import java.io.InputStream;
60 59 import java.nio.ByteBuffer;
61 60 import java.nio.IntBuffer;
@@ -289,7 +288,11 @@ public native int nativeCreateBinaryResource(
289 288
290 289 int mTextConsoleHeight;
291 290
  291 + /**
  292 + * Variables used to synchronize event posting.
  293 + */
292 294 private volatile boolean mIsSleeping;
  295 + private volatile boolean mIsEventPosted;
293 296
294 297 /**
295 298 * Ascent of text in the default console font.
@@ -340,6 +343,7 @@ public MoSyncThread(Context context, Handler handler) throws Exception
340 343 mHasDied = false;
341 344
342 345 mIsSleeping = false;
  346 + mIsEventPosted = false;
343 347
344 348 mMoSyncNetwork = new MoSyncNetwork(this);
345 349 mMoSyncSound = new MoSyncSound(this);
@@ -782,6 +786,7 @@ public synchronized ByteBuffer readInputStream(InputStream is) throws Exception
782 786 * @param data The data to fill the new data object with.
783 787 * @return The handle to the data if successful, <0 on error.
784 788 * If a placeholder is supplied, that value is returned on success.
  789 + *
785 790 * TODO: This method needs improved error checking.
786 791 */
787 792 public int createDataObject(int placeholder, byte[] data)
@@ -833,8 +838,14 @@ void storeIfBinaryAudioResource(int soundHandle)
833 838 * @param options The bitmapFactory options
834 839 *
835 840 * @return The created Bitmap, null if it failed
  841 + *
  842 + * TODO: There is no need for this method to be synchronized.
  843 + * Find out why it was synchronized.
836 844 */
837   - synchronized Bitmap decodeImageFromData(final byte[] data, final BitmapFactory.Options options)
  845 + //synchronized
  846 + Bitmap decodeImageFromData(
  847 + final byte[] data,
  848 + final BitmapFactory.Options options)
838 849 {
839 850 try
840 851 {
@@ -843,17 +854,31 @@ synchronized Bitmap decodeImageFromData(final byte[] data, final BitmapFactory.O
843 854 {
844 855 public void run()
845 856 {
846   - Bitmap bitmap = BitmapFactory.decodeByteArray(
  857 + // Here we can get:
  858 + // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
  859 + try
  860 + {
  861 + Bitmap bitmap = BitmapFactory.decodeByteArray(
847 862 data, 0, data.length, options);
848   -
849   - waiter.setResult(bitmap);
  863 + waiter.setResult(bitmap);
  864 + }
  865 + catch (OutOfMemoryError e1)
  866 + {
  867 + //Log.i("@@@", "decodeImageFromData - " + "Out of memory error : " + e1);
  868 + waiter.setResult(null);
  869 + }
  870 + catch (Throwable e2)
  871 + {
  872 + //Log.i("@@@", "decodeImageFromData - " + "Error : " + e2);
  873 + waiter.setResult(null);
  874 + }
850 875 }
851 876 });
852 877 return waiter.getResult();
853 878 }
854 879 catch(InterruptedException ie)
855 880 {
856   - Log.i("MoSync", "Couldn't decode image data.");
  881 + //Log.i("MoSync", "Couldn't decode image data.");
857 882 return null;
858 883 }
859 884 }
@@ -882,8 +907,15 @@ public void run()
882 907 * @param height The width of the created Bitmap
883 908 *
884 909 * @return The created Bitmap, null if it failed
  910 + *
  911 + * TODO: There is no need for this method to be synchronized.
  912 + * Find out why it was synchronized.
  913 + *
  914 + * TODO: Look into eliminating code duplication between
  915 + * createBitmap and createBitmapFromData.
885 916 */
886   - synchronized Bitmap createBitmap(final int width, final int height)
  917 + //synchronized
  918 + Bitmap createBitmap(final int width, final int height)
887 919 {
888 920 try
889 921 {
@@ -892,10 +924,25 @@ synchronized Bitmap createBitmap(final int width, final int height)
892 924 {
893 925 public void run()
894 926 {
895   - Bitmap bitmap = Bitmap.createBitmap(
  927 + // Here we can get:
  928 + // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
  929 + try
  930 + {
  931 + Bitmap bitmap = Bitmap.createBitmap(
896 932 width, height, Bitmap.Config.ARGB_8888);
897 933
898   - waiter.setResult(bitmap);
  934 + waiter.setResult(bitmap);
  935 + }
  936 + catch (OutOfMemoryError e1)
  937 + {
  938 + //Log.i("@@@", "createBitmapFromData - " + "Out of memory error : " + e1);
  939 + waiter.setResult(null);
  940 + }
  941 + catch (Throwable e2)
  942 + {
  943 + //Log.i("@@@", "createBitmapFromData - " + "Error : " + e2);
  944 + waiter.setResult(null);
  945 + }
899 946 }
900 947 });
901 948 return waiter.getResult();
@@ -915,8 +962,15 @@ public void run()
915 962 * @param pixels The pixel data
916 963 *
917 964 * @return The created Bitmap, null if it failed
  965 + *
  966 + * TODO: There is no need for this method to be synchronized.
  967 + * Find out why it was synchronized.
918 968 */
919   - synchronized Bitmap createBitmapFromData(final int width, final int height, final int[] pixels)
  969 + //synchronized
  970 + Bitmap createBitmapFromData(
  971 + final int width,
  972 + final int height,
  973 + final int[] pixels)
920 974 {
921 975 try
922 976 {
@@ -925,17 +979,32 @@ synchronized Bitmap createBitmapFromData(final int width, final int height, fina
925 979 {
926 980 public void run()
927 981 {
928   - Bitmap bitmap = Bitmap.createBitmap(
  982 + // Here we can get:
  983 + // java.lang.OutOfMemoryError: bitmap size exceeds VM budget
  984 + try
  985 + {
  986 + Bitmap bitmap = Bitmap.createBitmap(
929 987 pixels, width, height, Bitmap.Config.ARGB_8888);
930 988
931   - waiter.setResult(bitmap);
  989 + waiter.setResult(bitmap);
  990 + }
  991 + catch (OutOfMemoryError e1)
  992 + {
  993 + //Log.i("@@@", "createBitmapFromData - " + "Out of memory error : " + e1);
  994 + waiter.setResult(null);
  995 + }
  996 + catch (Throwable e2)
  997 + {
  998 + //Log.i("@@@", "createBitmapFromData - " + "Error : " + e2);
  999 + waiter.setResult(null);
  1000 + }
932 1001 }
933 1002 });
934 1003 return waiter.getResult();
935 1004 }
936 1005 catch(InterruptedException ie)
937 1006 {
938   - Log.i("MoSync", "Couldn't create bitmap from pixel data.");
  1007 + //Log.i("MoSync", "Couldn't create bitmap from pixel data.");
939 1008 return null;
940 1009 }
941 1010 }
@@ -953,11 +1022,14 @@ public void updateScreen()
953 1022 */
954 1023 public void postEvent(int[] event)
955 1024 {
956   - synchronized(mPostEventMonitor) {
  1025 + synchronized(mPostEventMonitor)
  1026 + {
957 1027 // Add event to queue.
958 1028 nativePostEvent(event);
959   - // Wake up thread if sleeping.
960   - if(mIsSleeping)
  1029 +
  1030 + mIsEventPosted = true;
  1031 +
  1032 + if (mIsSleeping)
961 1033 {
962 1034 interrupt();
963 1035 }
@@ -2149,7 +2221,7 @@ int _maCreateImageRaw(int placeholder, int width, int height, ByteBuffer buffer)
2149 2221
2150 2222 Bitmap bitmap = createBitmap(width, height);
2151 2223
2152   - if(null == bitmap)
  2224 + if (null == bitmap)
2153 2225 {
2154 2226 maPanic(1, "Unable to create ");
2155 2227 }
@@ -2170,7 +2242,6 @@ int maCreateDrawableImage(int placeholder, int width, int height)
2170 2242 SYSLOG("maCreateDrawableImage");
2171 2243 try
2172 2244 {
2173   -
2174 2245 Bitmap bitmap = createBitmap(width, height);
2175 2246
2176 2247 Canvas canvas = new Canvas(bitmap);
@@ -2445,7 +2516,17 @@ void maWait(int timeout)
2445 2516 {
2446 2517 SYSLOG("maWait");
2447 2518
2448   - mIsSleeping = true;
  2519 + synchronized(mPostEventMonitor)
  2520 + {
  2521 + if (mIsEventPosted)
  2522 + {
  2523 + mIsEventPosted = false;
  2524 + return;
  2525 + }
  2526 +
  2527 + mIsSleeping = true;
  2528 + }
  2529 +
2449 2530 try
2450 2531 {
2451 2532 if (timeout<=0)
@@ -2858,14 +2939,20 @@ boolean loadImage(int resourceIndex, int pos, int length, int binaryResource)
2858 2939
2859 2940 Bitmap bitmap = decodeImageFromData(ra, null);
2860 2941
  2942 + // TODO: Remove commencted out line.
2861 2943 //Bitmap bitmap = BitmapFactory.decodeByteArray(ra, 0, length);
2862   - if(bitmap != null)
  2944 +
  2945 + if (bitmap != null)
2863 2946 {
2864 2947 SYSLOG("Bitmap was created!");
2865 2948 mImageResources.put(
2866 2949 resourceIndex, new ImageCache(null, bitmap));
  2950 +
  2951 + // Return success.
2867 2952 return true;
2868 2953 }
  2954 +
  2955 + // If we end up here an error occurred.
2869 2956 logError("loadImage - Bitmap wasn't created from Resource: "
2870 2957 + resourceIndex);
2871 2958 return false;

0 comments on commit 36a4cdc

Please sign in to comment.
Something went wrong with that request. Please try again.