0

我正在尝试封装从我的主要活动中获取 Android 屏幕的屏幕截图。我有一个实现的类

ImageReader.IOnImageAvailableListner

 imageReader.SetOnImageAvailableListener(this, null)

在类中抛出一个强制转换异常(但不是编译异常)。我发现避免这种情况的唯一方法是让我的活动本身实现IOnImageAvailableListner。似乎 Xamarin/Mono 的某些部分确实需要参数SetOnImageAvailableListner是实现IOnImageAvailableListner.

这是我班的相关部分:

    public class Screenshooter : ImageReader.IOnImageAvailableListener
    {
        public void TakeScreenshot(Context context,
                                            Result resultCode,
                                            Intent data,
                                            IOnScreenshot onScreenshotCallback)
        {
            _context = context;
            _onScreenshot = onScreenshotCallback;

            _imageAvailableCount = 0;

            var size = new Point();
            ((Activity) context).WindowManager.DefaultDisplay.GetSize(size);
            _width = size.X;
            _height = size.Y;
            _imageReader = ImageReader.NewInstance(_width, _height, ImageFormatType.Rgb565, 2);
            MediaProjectionManager mediaProjectionManager  = (MediaProjectionManager) context.GetSystemService(Context.MediaProjectionService);

            if (_mediaProjection == null)
            {
                _mediaProjection =mediaProjectionManager.GetMediaProjection((int) resultCode, data);
                if (_mediaProjection == null)
                {
                    //                    Log.e(TAG, "MediaProjection null. Cannot take the screenshot.");
                    logger.Error("MediaProjection null. Cannot take the screenshot.");
                    return;
                }
            }
            try
            {
                _virtualDisplay = _mediaProjection.CreateVirtualDisplay("Screenshotter", _width, _height, (int) context .Resources.DisplayMetrics.DensityDpi, (DisplayFlags) DisplayManager.VirtualDisplayFlagAutoMirror, _imageReader.Surface, null, null);

                /////////////   THIS IS THE LINE THAT FAILS    ////////////
                _imageReader.SetOnImageAvailableListener(this, null);
                ///////////////////////////////////////////////////////////
            }
            catch (Exception ex)
            {
                logger.Error($"Error in {nameof(TakeScreenshot)}", ex);
                throw;
            }

            return;
        }
        //IOnImageAvailableListener Members

        public void OnImageAvailable(ImageReader reader)
        {
               // do stuff
         }

...
   }

我在请求屏幕截图的活动中实例化它:

public class MainActivity : Activity
{
    private void TakeScreenshot()
    {
        StartActivityForResult(((MediaProjectionManager) GetSystemService(MediaProjectionService)).CreateScreenCaptureIntent(),
                               REQUEST_CODE);
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
 {
     Screenshooter.GetInstance().takeScreenShot(this, resultCode, data, callback);
}

截图完成后调用的回调代码省略。

我到处都能看到这种模式的 Java android 代码示例。(具体来说,我一直在看这个例子:https ://github.com/omerjerk/Screenshotter )

我是 Android 和 Xamarin 的新手,但在 C# 方面拥有丰富的经验。

这是 Xamarin 中的错误吗?有解决办法吗?

谢谢

4

1 回答 1

0

我发现避免这种情况的唯一方法是让我的活动本身实现 IOnImageAvailableListner。

不,这不是唯一的方法,为了避免在活动类上实现接口,你正确地创建了自己的实现这个接口的类,例如:

public class MyImageReaderListener : Java.Lang.Object, ImageReader.IOnImageAvailableListener
{
    public void Dispose()
    {
        //TODO:
    }

    public void OnImageAvailable(ImageReader reader)
    {
        //TODO:
    }
}

强制转换异常是由于使用了this,它引用了Activity类,而这个类没有实现接口。如果您熟悉 C#,您应该能够理解这一点,您可以this在这里更改为您的类的新实例:

imagereader.SetOnImageAvailableListener(new MyImageReaderListener(), null);

对于像这样的代码:

Screenshotter.getInstance()
             .setSize(720, 1280)
             .takeScreenshot(this, resultCode, data, new ScreenshotCallback() {
                 @Override
                 public void onScreenshot(Bitmap bitmap) {
                     //Enjoy your bitmap
                 }
             });

C#没有java这样的匿名内部类,你可以参考C#匿名类可以实现接口吗?. 这就是我们创建一个类来实现接口的原因。

很多demo直接在activity上实现接口的原因是有时候我们需要监听器的返回值来继续我们的逻辑工作,你可以查看Xamarin for Events and Listeners的Api设计。

于 2017-08-15T07:49:08.347 回答