2

When loading certain .swf files into a WebView, a split second after the flash file begins to be displayed, my app closes with a Signal 11 fault. No exception is thrown that I can see. Example LogCat dump here.

When loading the same .swf files into the stock Android browser, instead of closing, an error icon is displayed. Touching it opens a pop-up stating: "Adobe Flash; Insufficient Memory".

My question is: Is there any way to catch the Insufficient Memory error before the SIGSEGV occurs -- preventing the task from being terminated -- as is done by the stock browser? Any help would be greatly appreciated!


Note: I'm testing under Android 2.2 with the HTC version of the Flash plugin, but it appears that the same sort of issues occur on other, non-HTC devices. I'm loading the swf file into the WebView directly, using:

webView.loadUrl("http://whatever.com/bla.swf");

(with plugins and JavaScript enabled). It works perfectly in most cases -- only a few files cause problems. I've tried various suggestions for reducing memory (such as clearing the WebView caches) without success.

Sven Viking
  • 2,660
  • 21
  • 34
  • Added a related question here: http://stackoverflow.com/questions/6185407/prevent-flash-player-fault-in-webview-as-is-done-by-the-android-browser . While it is regarding the same basic issue, it is a separate question, as this question was largely based upon a false premise (thanks to Adobe's misleading error messages). – Sven Viking May 31 '11 at 09:53

2 Answers2

3

An alternative solution could be to use a background task or service to monitor the memory usage on the device, if the system tells you that you're on low memory, kill the flash activity.

To know if you are on low memory you can use this code:

ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); 
activityManager.getMemoryInfo(memoryInfo);

boolean onLowMemory = memoryInfo.lowMemory;

Or you can check the available memory using memoryInfo.availMem, if it's too low (close to memoryInfo.threshold) kill your activity before the exception.

Trasplazio Garzuglio
  • 3,535
  • 2
  • 25
  • 25
  • Thanks! Assuming there's no simpler solution (which, judging by the lack of responses, seems rather likely), that sounds like it could work! Just so I know, I guess there's a reason for using a separate task or service to do this rather than a thread? – Sven Viking May 30 '11 at 04:43
  • the recommended way is to use an AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html If you use a thread and onDestroy is called you lose the reference to the thread in your activity, though you can save it with onRetainNonConfigurationInstance() and retrieve it with getLastNonConfigurationInstance(). – Trasplazio Garzuglio May 30 '11 at 13:02
  • OK, thanks again! That's easier anyway. Any idea of what sort of interval could be used between checks? I'm guessing they'd need to be quite frequent to make sure they catch the problem. – Sven Viking May 30 '11 at 13:42
  • I would expect the memory to increase more or less linearly with time so another possibility would be to calculate how much the memory usage increases when you launch the task by monitoring it for a short interval of time, then predict at what time the memory available is going to be too low. Your solution should also works and is probably easier, I guess you have to experiment a little bit to tune the interval but I would do it frequently. – Trasplazio Garzuglio May 30 '11 at 13:52
  • OK, thanks again. Unfortunately I'm not sure Flash will always load things into memory at a constant rate. In one file the fault doesn't occur until half-way through a video, for example, so it probably varies considerably depending on the file being used. – Sven Viking May 30 '11 at 14:04
  • Hmm, unfortunately, this doesn't appear to solve the problem. Even with the asyncTask checking constantly (no wait), it doesn't detect `memoryInfo.lowMemory` as becoming `true` before the SIGSEGV comes through. Perhaps it's not caused by a memory overflow, but some other bad memory access due to a bug in the Flash Player plugin? I have no idea. Just wish I knew how the stock browser avoids this problem. Can Flash Player be encapsulated in its own Task somehow so the SIGSEGV only terminates it, perhaps?... Or even the WebView itself?... I have very limited knowledge of these things. – Sven Viking May 31 '11 at 06:07
  • Yeah, if `ActivityManager.MemoryInfo()` is correct, there's still quite a lot of AvailaleMemory when the SIGSEGV fault occurs. Presumably it's not actually an OutOfMemory fault, but is incorrectly reported as such by Flash Player when run in the Android browser. So probably the question was unintentionally wrong, and this would have been a good solution had the question been correct. – Sven Viking May 31 '11 at 07:47
  • 1
    Hi Sven, sorry to hear that your problem is still not solved. You can't launch the flash player standalone as it's a plugin for the browser but there are other flash players on the market you can try. – Trasplazio Garzuglio May 31 '11 at 14:07
-1

I think you need to handle the kill even in onPause()

On the link below you would see a table of all the methods in activity that you can override. It has one column called killable. Which indicates can this methods be killed. As onDestroy() is a killable methods there is a chance that it may not be called. But onPause() is not killable so u can handle you logic of saving state or anything else here. Activity

anargund
  • 3,249
  • 2
  • 21
  • 25
  • Thanks. However, I just checked, and in this case OnPause() was not called on five out of six attempts. Also, what I want to do is prevent the termination entirely, as is done by the stock web browser. – Sven Viking May 22 '11 at 05:29