Xamarin.Forms和Plugin.Media:大约20张照片后发生了一些崩溃

时间:2017-04-08 23:58:43

标签: xamarin.forms

我对Xamarin.Forms ver有疑问。 2.3.4.224和Plugin.Media ver。 2.6.2。拍摄约20张照片后出现此问题(取决于设备):基本上应用程序崩溃时没有任何明显的原因。

如果您想复制错误,我在GitHub为您创建了一个测试项目。使用我的iPad Air或iPad Pro约30张照片后(视频iPad Air - iPad Pro)。所有设备都是iOS版本。 10.3.1并且它们有足够的空间存放照片。

该应用程序非常简单:您有两个按钮用于拍照,另一个用于选择照片。如果您在大约20个(iPad Air中为32个)之后一个接一个地拍照,应用程序会崩溃。我只是用Plugin.Media拍照了。

欢迎任何想法。

更新

在我的项目中,我引用了Refractored.MvvmHelpers,我注意到如果删除它,我可以拍摄更多照片。我用BaseViewModel创建了我的INotifyPropertyChanged,我注意到我可以拍摄更多照片。

我在没有MVVM的情况下创建了一个新项目(您可以在cameratesteasy下的GitHub上找到它),并且只有代码可以拍摄照片:

public partial class cameratesteasyPage : ContentPage
{
    int count = 0;

    public cameratesteasyPage()
    {
        InitializeComponent();
        CrossMedia.Current.Initialize();
    }

    void UpdateCount()
    {
        count++;
        CountLabel.Text = $"{count} times";
    }

    async void StartCameraTapped(object sender, System.EventArgs args)
    {
        using (var file = await CrossMedia.Current.TakePhotoAsync(
                          new StoreCameraMediaOptions {}))
        {
            if (file == null)
                return;

            UpdateCount();
        }
    }

    async void StartCameraTakeTapped(object sender, System.EventArgs args)
    {
        var file = await CrossMedia.Current.PickPhotoAsync();

        if (file == null)
            return;

        UpdateCount();
    }
}

在这种情况下,应用程序在52张照片后关闭。我保存了Xcode的日志,您可以看到它here

我使用Xamarin Profile并且内存级别始终很低。大约30张照片后,Xamarin Profiler

出错

Xamarin Profiler error

Xamarin Profiler error 2 Xamarin Profiler error 3

最后,我可以创建一个Xamarin Profiler file

另外我注意到iPad上会出现这种错误。 iPhone中的相同应用程序工作正常(显然)或者我在崩溃前没有找到照片的数量。

更新/ 2

我决定实现拍照的原生功能。

接口

public interface ICamera
{
    void TakePicture();
}

实施

using System;
using cameratest.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;

[assembly: Xamarin.Forms.Dependency(typeof(Camera_iOS))]
namespace cameratest.iOS
{
    public class Camera_iOS : ICamera
    {
        static UIImagePickerController picker;
        static Action<NSDictionary> _callback;

        static void Init()
        {
            if (picker != null)
                return;

            picker = new UIImagePickerController();
            picker.Delegate = new CameraDelegate();
        }

        class CameraDelegate : UIImagePickerControllerDelegate
        {
            public override void FinishedPickingMedia(
                                 UIImagePickerController picker, NSDictionary info)
            {
                var cb = _callback;
                _callback = null;

                picker.DismissModalViewController(true);
                cb(info);
            }
        }

        public static void TakePicture(UIViewController parent, 
                                       Action<NSDictionary> callback)
        {
            Init();
            picker.SourceType = UIImagePickerControllerSourceType.Camera;
            _callback = callback;
            parent.PresentModalViewController(picker, true);
        }

        public static void SelectPicture(UIViewController parent, 
                                         Action<NSDictionary> callback)
        {
            Init();
            picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            _callback = callback;
            parent.PresentModalViewController(picker, true);
        }

        public void TakePicture()
        {
            var rc = UIApplication.SharedApplication.KeyWindow.RootViewController;
            TakePicture(rc, (obj) =>
            {
                var photo = obj.ValueForKey(
                         new NSString("UIImagePickerControllerOriginalImage")) as UIImage;
                var documentsDirectory = 
                         Environment.GetFolderPath(Environment.SpecialFolder.Personal);

                // hardcoded filename, overwritten each time
                string jpgFilename = System.IO.Path.Combine(documentsDirectory, 
                         "Photo.jpg");
                NSData imgData = photo.AsJPEG();
                NSError err = null;
                if (imgData.Save(jpgFilename, false, out err))
                {
                    Console.WriteLine("saved as " + jpgFilename);
                }
                else
                {
                    Console.WriteLine("NOT saved as " + 
                         jpgFilename + " because" + err.LocalizedDescription);
                }
            });
        }
    }
}

在大约30张照片后使用此代码,应用程序崩溃。唯一的区别是这个代码我可以从ReceiveMemoryWarning收到一些警报。如果您有兴趣,我会更新GitHub上的代码。

0 个答案:

没有答案