diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
index 5b39aa3dfb..7dd09df73c 100644
--- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
+++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
@@ -29,12 +29,15 @@
4
True
None
- False
+ True
False
False
- armeabi,armeabi-v7a,x86
+ armeabi;armeabi-v7a;x86
Xamarin
False
+ False
+ False
+ False
pdbonly
diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs
index 3f357b0e70..157609088f 100644
--- a/samples/ControlCatalog.Android/MainActivity.cs
+++ b/samples/ControlCatalog.Android/MainActivity.cs
@@ -1,9 +1,8 @@
using System;
using Android.App;
-
using Android.OS;
using Android.Content.PM;
-using Avalonia.Android.Platform.Specific;
+using Avalonia.Android;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
@@ -17,29 +16,16 @@ namespace ControlCatalog.Android
[Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
public class MainActivity : AvaloniaActivity
{
- public MainActivity() : base(typeof (App))
- {
-
- }
-
protected override void OnCreate(Bundle savedInstanceState)
{
- base.OnCreate(savedInstanceState);
-
- App app;
- if (Avalonia.Application.Current != null)
- app = (App)Avalonia.Application.Current;
- else
+ if (Avalonia.Application.Current == null)
{
- app = new App();
- AppBuilder.Configure(app)
+ AppBuilder.Configure(new App())
.UseAndroid()
- .UseSkia()
.SetupWithoutStarting();
+ Content = new MainView();
}
-
- var mainWindow = new MainWindow();
- app.Run(mainWindow);
+ base.OnCreate(savedInstanceState);
}
}
}
diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs
index afaa314e6c..5b3170a0c7 100644
--- a/src/Android/Avalonia.Android/AndroidPlatform.cs
+++ b/src/Android/Avalonia.Android/AndroidPlatform.cs
@@ -1,5 +1,8 @@
using System;
using System.IO;
+using System.Linq;
+using Android.Content;
+using Android.Views;
using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.SkiaPlatform;
@@ -8,6 +11,7 @@ using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Platform;
+using Avalonia.Rendering;
using Avalonia.Shared.PlatformSupport;
using Avalonia.Skia;
@@ -17,7 +21,8 @@ namespace Avalonia
{
public static T UseAndroid(this T builder) where T : AppBuilderBase, new()
{
- builder.UseWindowingSubsystem(Android.AndroidPlatform.Initialize, "Android");
+ builder.UseWindowingSubsystem(() => Android.AndroidPlatform.Initialize(builder.Instance), "Android");
+ builder.UseSkia();
return builder;
}
}
@@ -25,7 +30,7 @@ namespace Avalonia
namespace Avalonia.Android
{
- public class AndroidPlatform : IPlatformSettings, IWindowingPlatform
+ class AndroidPlatform : IPlatformSettings, IWindowingPlatform
{
public static readonly AndroidPlatform Instance = new AndroidPlatform();
public Size DoubleClickSize => new Size(4, 4);
@@ -40,7 +45,7 @@ namespace Avalonia.Android
_scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity;
}
- public static void Initialize()
+ public static void Initialize(Avalonia.Application app)
{
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
@@ -51,24 +56,22 @@ namespace Avalonia.Android
.Bind().ToConstant(new AndroidThreadingInterface())
.Bind().ToTransient()
.Bind().ToConstant(Instance)
- .Bind().ToSingleton();
+ .Bind().ToSingleton()
+ .Bind().ToConstant(new DefaultRenderLoop(60))
- SkiaPlatform.Initialize();
- }
+ .Bind().ToConstant(new AssetLoader(app.GetType().Assembly));
- public void Init(Type applicationType)
- {
- StandardRuntimePlatformServices.Register(applicationType.Assembly);
+ SkiaPlatform.Initialize();
}
public IWindowImpl CreateWindow()
{
- return new WindowImpl();
+ throw new NotSupportedException();
}
public IEmbeddableWindowImpl CreateEmbeddableWindow()
{
- throw new NotImplementedException();
+ throw new NotSupportedException();
}
public IPopupImpl CreatePopup()
diff --git a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
index b4059e3114..6327be12a5 100644
--- a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
+++ b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
@@ -51,10 +51,16 @@ namespace Avalonia.Android
scheduled = true;
EnsureInvokeOnMainThread(() =>
{
- tick();
- lock (l)
+ try
{
- scheduled = false;
+ tick();
+ }
+ finally
+ {
+ lock (l)
+ {
+ scheduled = false;
+ }
}
});
}
diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj
index 654cb13678..e84146ffb3 100644
--- a/src/Android/Avalonia.Android/Avalonia.Android.csproj
+++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj
@@ -63,16 +63,15 @@
+
+
-
-
+
-
-
diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs
new file mode 100644
index 0000000000..a9b04c882b
--- /dev/null
+++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+
+namespace Avalonia.Android
+{
+ public abstract class AvaloniaActivity : Activity
+ {
+ AvaloniaView _view;
+ object _content;
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ RequestWindowFeature(WindowFeatures.NoTitle);
+ _view = new AvaloniaView(this);
+ if(_content != null)
+ _view.Content = _content;
+ SetContentView(_view);
+ TakeKeyEvents(true);
+ base.OnCreate(savedInstanceState);
+ }
+
+ public object Content
+ {
+ get
+ {
+ return _content;
+ }
+ set
+ {
+ _content = value;
+ if (_view != null)
+ _view.Content = value;
+ }
+ }
+
+ public override bool DispatchKeyEvent(KeyEvent e)
+ {
+ return _view.DispatchKeyEvent(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/AvaloniaView.cs b/src/Android/Avalonia.Android/AvaloniaView.cs
new file mode 100644
index 0000000000..71eea14a1d
--- /dev/null
+++ b/src/Android/Avalonia.Android/AvaloniaView.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using Avalonia.Android.Platform.SkiaPlatform;
+using Avalonia.Controls.Embedding;
+using Avalonia.Platform;
+
+namespace Avalonia.Android
+{
+ public class AvaloniaView : FrameLayout
+ {
+ private readonly EmbeddableControlRoot _root;
+ private readonly ViewImpl _view;
+
+ public AvaloniaView(Context context) : base(context)
+ {
+ _view = new ViewImpl(context);
+ AddView(_view);
+ _root = new EmbeddableControlRoot(_view);
+ _root.Prepare();
+ }
+
+ public object Content
+ {
+ get { return _root.Content; }
+ set { _root.Content = value; }
+ }
+
+ public override bool DispatchKeyEvent(KeyEvent e)
+ {
+ return _view.DispatchKeyEvent(e);
+ }
+
+ class ViewImpl : TopLevelImpl, IEmbeddableWindowImpl
+ {
+ public event Action LostFocus;
+
+ public ViewImpl(Context context) : base(context)
+ {
+ Focusable = true;
+ FocusChange += ViewImpl_FocusChange;
+ }
+
+ private void ViewImpl_FocusChange(object sender, FocusChangeEventArgs e)
+ {
+ if(!e.HasFocus)
+ LostFocus?.Invoke();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs
deleted file mode 100644
index 690c509b53..0000000000
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Android.Views;
-using Avalonia.Android.Platform.Specific;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Platform;
-
-namespace Avalonia.Android.Platform.SkiaPlatform
-{
- public class MainWindowImpl :
- WindowImpl
- , IWindowImpl
- {
- public MainWindowImpl()
- {
- }
-
- public new WindowState WindowState
- {
- get { return WindowState.Normal; }
- set { }
- }
-
- protected override void Init()
- {
- base.Init();
-
- HandleEvents = true;
- _keyboardHelper.ActivateAutoShowKeybord();
- }
-
- void ITopLevelImpl.Show()
- {
- (Parent as ViewGroup)?.RemoveAllViews();
- AvaloniaLocator.Current.GetService().ContentView = this;
- //this.Visibility = ViewStates.Visible;
- }
-
- void ITopLevelImpl.SetInputRoot(IInputRoot inputRoot)
- {
- base.SetInputRoot(inputRoot);
- _keyboardHelper.UpdateKeyboardState(inputRoot);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
similarity index 86%
rename from src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs
rename to src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 17b1cfba0a..1687432bb3 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -14,25 +14,21 @@ using Avalonia.Controls;
namespace Avalonia.Android.Platform.SkiaPlatform
{
- public class WindowImpl : SkiaView, IAndroidView, IWindowImpl, ISurfaceHolderCallback
+ class TopLevelImpl : SkiaView, IAndroidView, ITopLevelImpl, ISurfaceHolderCallback
{
- protected AndroidKeyboardEventsHelper _keyboardHelper;
+ protected AndroidKeyboardEventsHelper _keyboardHelper;
- private AndroidTouchEventsHelper _touchHelper;
+ private AndroidTouchEventsHelper _touchHelper;
- public WindowImpl(Context context) : base((Activity)context)
+ public TopLevelImpl(Context context) : base(context)
{
- _keyboardHelper = new AndroidKeyboardEventsHelper(this);
- _touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot, p => GetAvaloniaPointFromEvent(p));
+ _keyboardHelper = new AndroidKeyboardEventsHelper(this);
+ _touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot, p => GetAvaloniaPointFromEvent(p));
MaxClientSize = new Size(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels);
ClientSize = MaxClientSize;
- Init();
- }
-
- public WindowImpl() : this(AvaloniaLocator.Current.GetService().Activity)
- {
}
+
void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
{
@@ -46,11 +42,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
base.SurfaceChanged(holder, format, width, height);
}
-
- protected virtual void Init()
- {
- }
-
+
private bool _handleEvents;
public bool HandleEvents
diff --git a/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs b/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs
deleted file mode 100644
index 4ccff10455..0000000000
--- a/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using Android.App;
-using Android.OS;
-using Android.Views;
-using Android.Widget;
-
-namespace Avalonia.Android.Platform.Specific
-{
- public class AvaloniaActivity : Activity, IAndroidActivity
- {
- private IAndroidView _contentView;
-
- public AvaloniaActivity(Type applicationType)
- {
- AndroidPlatform.Instance.Init(applicationType);
- }
-
- public Activity Activity => this;
-
- public IAndroidView ContentView
- {
- get
- {
- return this._contentView;
- }
-
- set
- {
- this._contentView = value;
- var fl = new FrameLayout(this);
- fl.AddView(this._contentView.View);
- //this.SetContentView(value.View);
- this.SetContentView(fl);
- }
- }
-
- protected override void OnCreate(Bundle savedInstanceState)
- {
- AvaloniaLocator.CurrentMutable.Bind().ToConstant(this);
- RequestWindowFeature(WindowFeatures.NoTitle);
- base.OnCreate(savedInstanceState);
- }
-
- public override void SetContentView(View view)
- {
- base.SetContentView(view);
- TakeKeyEvents(true);
- }
-
- public override bool DispatchKeyEvent(KeyEvent e)
- {
- if (_contentView != null)
- {
- _contentView.View.DispatchKeyEvent(e);
- }
-
- return base.DispatchKeyEvent(e);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
index 17e1f62e8c..7bac0ff814 100644
--- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
+++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
@@ -12,7 +12,7 @@ using System.ComponentModel;
namespace Avalonia.Android.Platform.Specific.Helpers
{
- public class AndroidKeyboardEventsHelper : IDisposable where TView : View, IWindowImpl, IAndroidView
+ public class AndroidKeyboardEventsHelper : IDisposable where TView : View, ITopLevelImpl, IAndroidView
{
private TView _view;
private IInputElement _lastFocusedElement;
diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
index c6d1833d2d..a448044ee6 100644
--- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
+++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
@@ -8,7 +8,7 @@ using System;
namespace Avalonia.Android.Platform.Specific.Helpers
{
- public class AndroidTouchEventsHelper : IDisposable where TView : View, IWindowImpl, IAndroidView
+ public class AndroidTouchEventsHelper : IDisposable where TView : View, ITopLevelImpl, IAndroidView
{
private TView _view;
public bool HandleEvents { get; set; }
diff --git a/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs b/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs
deleted file mode 100644
index b2a999d4be..0000000000
--- a/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Android.App;
-using Android.Views;
-
-namespace Avalonia.Android.Platform.Specific
-{
- public interface IAndroidActivity
- {
- Activity Activity { get; }
-
- IAndroidView ContentView { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
index e004121323..ebe268adcf 100644
--- a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
+++ b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
@@ -20,7 +20,7 @@
Properties\AndroidManifest.xml
- true
+ True
full
false
bin\Debug\
@@ -29,16 +29,16 @@
4
True
None
-
- False
+ True
False
False
- armeabi,armeabi-v7a,x86
-
-
+ armeabi;armeabi-v7a;x86
Xamarin
False
True
+ False
+ False
+ False
pdbonly
diff --git a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
index ff27e12f6e..7973ad72e5 100644
--- a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
+++ b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
@@ -2,7 +2,7 @@ using System;
using Android.App;
using Android.Content.PM;
using Android.OS;
-using Avalonia.Android.Platform.Specific;
+using Avalonia.Android;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
@@ -17,36 +17,24 @@ namespace Avalonia.AndroidTestApplication
Icon = "@drawable/icon",
LaunchMode = LaunchMode.SingleInstance/*,
ScreenOrientation = ScreenOrientation.Landscape*/)]
- public class MainBaseActivity : AvaloniaActivity
+ public class MainBaseActivity : Activity
{
- public MainBaseActivity() : base(typeof (App))
- {
-
- }
-
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
-
- App app;
- if (Avalonia.Application.Current != null)
- app = (App)Avalonia.Application.Current;
- else
+ if (Avalonia.Application.Current == null)
{
- app = new App();
- AppBuilder.Configure(app)
+ AppBuilder.Configure()
.UseAndroid()
- .UseSkia()
.SetupWithoutStarting();
}
-
- app.Run();
+ SetContentView(new AvaloniaView(this) { Content = App.CreateSimpleWindow() });
}
}
public class App : Application
{
- public void Run()
+ public override void Initialize()
{
Styles.Add(new DefaultTheme());
@@ -55,18 +43,14 @@ namespace Avalonia.AndroidTestApplication
new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"));
Styles.Add(baseLight);
- var wnd = App.CreateSimpleWindow();
- wnd.AttachDevTools();
- Run(wnd);
}
// This provides a simple UI tree for testing input handling, drawing, etc
- public static Window CreateSimpleWindow()
+ public static ContentControl CreateSimpleWindow()
{
- Window window = new Window
+ ContentControl window = new ContentControl()
{
- Title = "Avalonia Test Application",
Background = Brushes.Red,
Content = new StackPanel
{
diff --git a/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj b/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj
index fdde5553eb..35c7af454b 100644
--- a/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj
+++ b/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj
@@ -89,6 +89,7 @@
+
diff --git a/src/Skia/Avalonia.Skia.Android/NativeMethods.cs b/src/Skia/Avalonia.Skia.Android/NativeMethods.cs
new file mode 100644
index 0000000000..b9557c00c7
--- /dev/null
+++ b/src/Skia/Avalonia.Skia.Android/NativeMethods.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+
+namespace Avalonia.Skia.Android
+{
+ static class NativeMethods
+ {
+ [DllImport("android")]
+ internal static extern IntPtr ANativeWindow_fromSurface(IntPtr jniEnv, IntPtr handle);
+
+ [DllImport("android")]
+ internal static extern void ANativeWindow_release(IntPtr window);
+ [DllImport("android")]
+ internal static extern void ANativeWindow_unlockAndPost(IntPtr window);
+
+ [DllImport("android")]
+ internal static extern int ANativeWindow_lock(IntPtr window, out ANativeWindow_Buffer outBuffer, ref ARect inOutDirtyBounds);
+ public enum AndroidPixelFormat
+ {
+ WINDOW_FORMAT_RGBA_8888 = 1,
+ WINDOW_FORMAT_RGBX_8888 = 2,
+ WINDOW_FORMAT_RGB_565 = 4,
+ }
+
+ internal struct ARect
+ {
+ public int left;
+ public int top;
+ public int right;
+ public int bottom;
+ }
+
+
+ internal struct ANativeWindow_Buffer
+ {
+ // The number of pixels that are show horizontally.
+ public int width;
+
+ // The number of pixels that are shown vertically.
+ public int height;
+
+ // The number of *pixels* that a line in the buffer takes in
+ // memory. This may be >= width.
+ public int stride;
+
+ // The format of the buffer. One of WINDOW_FORMAT_*
+ public AndroidPixelFormat format;
+
+ // The actual bits.
+ public IntPtr bits;
+
+ // Do not touch.
+ uint reserved1;
+ uint reserved2;
+ uint reserved3;
+ uint reserved4;
+ uint reserved5;
+ uint reserved6;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia.Android/RenderTarget.cs b/src/Skia/Avalonia.Skia.Android/RenderTarget.cs
index 03ddf49851..2ee8d5a839 100644
--- a/src/Skia/Avalonia.Skia.Android/RenderTarget.cs
+++ b/src/Skia/Avalonia.Skia.Android/RenderTarget.cs
@@ -3,7 +3,9 @@ using Avalonia.Media;
using Avalonia.Platform;
using SkiaSharp;
using Android.Graphics;
+using Android.Runtime;
using Android.Views;
+using Avalonia.Skia.Android;
namespace Avalonia.Skia
{
@@ -27,49 +29,38 @@ namespace Avalonia.Skia
internal class WindowRenderTarget : RenderTarget
{
private readonly SurfaceView _surfaceView;
- Bitmap _bitmap;
- int Width { get; set; }
- int Height { get; set; }
+ private IntPtr _window;
public WindowRenderTarget(SurfaceView surfaceView)
{
_surfaceView = surfaceView;
- FixSize();
}
- private void FixSize()
+ private void PrepareForDraw()
{
- int width, height;
- GetPlatformWindowSize(out width, out height);
- if (Width == width && Height == height)
- return;
-
- Width = width;
- Height = height;
-
- if (Surface != null)
- {
- Surface.Dispose();
- }
-
- if (_bitmap != null)
- {
- _bitmap.Dispose();
- }
-
- _bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
- Surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, _bitmap.LockPixels(), width * 4);
- }
-
- private void GetPlatformWindowSize(out int w, out int h)
- {
- w = _surfaceView.Width;
- h = _surfaceView.Height;
+ int width = _surfaceView.Width;
+ var height = _surfaceView.Height;
+
+ _window = NativeMethods.ANativeWindow_fromSurface(JNIEnv.Handle, _surfaceView.Holder.Surface.Handle);
+ var buffer = new NativeMethods.ANativeWindow_Buffer();
+ var rc = new NativeMethods.ARect() {right = width, bottom = height};
+ NativeMethods.ANativeWindow_lock(_window, out buffer, ref rc);
+
+ var colorType = buffer.format == NativeMethods.AndroidPixelFormat.WINDOW_FORMAT_RGB_565
+ ? SKColorType.Rgb565 : SKImageInfo.PlatformColorType;
+
+ var stride = buffer.stride * (colorType == SKColorType.Rgb565 ? 2 : 4);
+
+ Surface = SKSurface.Create(buffer.width, buffer.height, colorType,
+ SKAlphaType.Premul, buffer.bits, stride);
+
+ if (Surface == null)
+ throw new Exception("Unable to create Skia surface");
}
public override DrawingContext CreateDrawingContext()
{
- FixSize();
+ PrepareForDraw();
var canvas = Surface.Canvas;
canvas.RestoreToCount(0);
@@ -84,23 +75,11 @@ namespace Avalonia.Skia
public void Present()
{
- Canvas canvas = null;
- try
- {
- canvas = _surfaceView.Holder.LockCanvas(null);
- _bitmap.UnlockPixels();
- canvas.DrawBitmap(_bitmap, 0, 0, null);
- }
- catch (Exception)
- {
- }
- finally
- {
- if (canvas != null)
- _surfaceView.Holder.UnlockCanvasAndPost(canvas);
- }
-
- _bitmap.UnlockPixels();
+ Surface?.Dispose();
+ Surface = null;
+ NativeMethods.ANativeWindow_unlockAndPost(_window);
+ NativeMethods.ANativeWindow_release(_window);
+ _window = IntPtr.Zero;
}
}
}
diff --git a/src/Skia/Avalonia.Skia.Android/SkiaView.cs b/src/Skia/Avalonia.Skia.Android/SkiaView.cs
index a45a80cf18..f69462f087 100644
--- a/src/Skia/Avalonia.Skia.Android/SkiaView.cs
+++ b/src/Skia/Avalonia.Skia.Android/SkiaView.cs
@@ -18,12 +18,12 @@ namespace Avalonia.Skia.Android
{
public abstract class SkiaView : SurfaceView, ISurfaceHolderCallback, IPlatformHandle
{
- private readonly Activity _context;
+ private readonly Context _context;
bool _invalidateQueued;
readonly object _lock = new object();
private readonly Handler _handler;
- public SkiaView(Activity context) : base(context)
+ public SkiaView(Context context) : base(context)
{
_context = context;
Holder.AddCallback(this);