开发者

Mono for Android exit code 255 on BitmapFactory.DecodeStream

开发者 https://www.devze.com 2023-04-06 21:43 出处:网络
I\'m using Mono for Android (latest version as of this post) with the Visual Studio plugin to build an Android application. It targets API Level 8, Android 2.2 framework.

I'm using Mono for Android (latest version as of this post) with the Visual Studio plugin to build an Android application. It targets API Level 8, Android 2.2 framework.

The app runs fine on a Motorola Droid running Android version 2.2.2 It crashes with almost no output from the debugger on Motorola Droid X2 running Android 2.3.3

The only output is: The program 'Mono' has exited with code 255 (0xff).

The crash happens in this method on the line that starts with using (Bitmap...

public static Drawable GetDrawable(string url) {
    try {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using (Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeStream(response.GetResponseStream())) {
            Drawable image = (Drawable)(new BitmapDrawable(bitmap));
            return image;
        }
    }
    catch {
        return null;
    }
}

If I set a breakpoint on that line it breaks correctly but I can't find anything wrong. If I set a breakpoint after that line the debugger simply detaches and the app force quits.

I have a similar method that returns an object from JSON and it works fine. So, I'm fairly sure it's related to the dynamic bitmap creation but at this point I've tried everything I can think of.

UPDATE:

I just reproduced this problem in a small, self-contained project available here: DrawableTest.zip

Here's the full code:

using System;
using System.Net;
using System.Threading;
using Android.App;
using Android.Widget;
using Android.OS;
using Android.Graphics;
using Android.Graphics.Drawables;

namespace DrawableTest {
    [Activity(Label = "DrawableTest", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity {

        ImageView mImage;
        Button mButton;
        public const string mImageUrl = "http://i.stpost.com/erez4/erez?src=ProductImages/3576U_02.tif&tmp=MediumLargeG4&redirect=0&headers=proxy";

        protected override void OnCreate(Bundle bundle) {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.Main);

            mImage = FindViewById<ImageView>(Resource.Id.MyImage);
            mButton = FindViewById<Button>(Resource.Id.MyButton);

            mButton.Click += new EventHandler(mButton_Click);
        }

        void mButton_Click(object sender, EventArgs e) {
            ThreadPool.QueueUserWorkItem(o => AsyncImageLoad());
        }

        private Drawable GetDrawable(string url) {
            try {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeSt开发者_如何转开发ream(response.GetResponseStream())) {
                    Drawable image = new BitmapDrawable(bitmap);
                    return image;
                }
            }
            catch (Exception e) {
                return null;
            }
        }

        private void AsyncImageLoad() {
            Drawable image = GetDrawable(mImageUrl);

            RunOnUiThread(() => {
                mImage.SetImageDrawable(image);
            });
        }
    }
}


This is probably a bug in our Stream mapping code, similar to: http://bugzilla.xamarin.com/show_bug.cgi?id=1054

This should be fixed in the next release (1.9.x, probably).

As a workaround, try copying response.GetResponseStream() into a System.IO.MemoryStream, and then pass the MemoryStream to BitmapFactory.DecodeStream().

Update

I had the right idea, but the wrong approach. Instead of using BitmapFactory.DecodeStream(), use BitmapFactory.DecodeByteArray(). The following code works for me in your DrawableTest.zip app:

private Drawable GetDrawable(string url)
{
    try {
        HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(url);
        using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
        using (Stream responseStream = response.GetResponseStream()) {
            MemoryStream workaround = new MemoryStream();
            responseStream.CopyTo(workaround);

            Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeByteArray (
                    workaround.GetBuffer (), 0, (int) workaround.Length);
            Drawable image = new BitmapDrawable(bitmap);
            return image;
        }
    }
    catch (Exception e) {
        Log.Error("DrawableTest", "Exception: " + e.Message);
        return null;
    }
}

Note the using blocks to ensure that the resources are disposed.


Try running without the debugger (Ctrl-F5), and then checking the Android Debug Log for the exception:

http://android.xamarin.com/Documentation/Guides/Android_Debug_Log

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号