From 81bccd64ca87ebefad50658b7c0703d2b302f06b Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Fri, 21 Nov 2025 09:57:25 +0000 Subject: [PATCH] wip --- .../Previewer/PreviewFactoryActivity.cs | 16 ++++++- .../Previewer/PreviewerConnection.cs | 42 ++++++++++++------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Android/Avalonia.Android/Previewer/PreviewFactoryActivity.cs b/src/Android/Avalonia.Android/Previewer/PreviewFactoryActivity.cs index 978af5c283..48c972f225 100644 --- a/src/Android/Avalonia.Android/Previewer/PreviewFactoryActivity.cs +++ b/src/Android/Avalonia.Android/Previewer/PreviewFactoryActivity.cs @@ -1,4 +1,6 @@ using System; +using System.Net; +using System.Net.Sockets; using System.Reflection; using Android.App; using Android.Content; @@ -16,7 +18,7 @@ namespace Avalonia.Android.Previewer if (OperatingSystem.IsAndroidVersionAtLeast(26)) { var currentIntent = this.Intent; - var port = currentIntent?.GetIntExtra("port", 0) ?? 0; + var port = FreeTcpPort(); if (port != 0) { var metrics = this.Resources?.DisplayMetrics; @@ -33,10 +35,22 @@ namespace Avalonia.Android.Previewer presentation.Show(); } } + + global::Android.Util.Log.Info("AVALONIA_PREVIEW", $"Previewer started at port-{port}"); } } Finish(); } + + protected static int FreeTcpPort() + { + var l = new TcpListener(IPAddress.Loopback, 0); + l.Start(); + int port = ((IPEndPoint)l.LocalEndpoint).Port; + l.Stop(); + l.Dispose(); + return port; + } } } diff --git a/src/Android/Avalonia.Android/Previewer/PreviewerConnection.cs b/src/Android/Avalonia.Android/Previewer/PreviewerConnection.cs index 7381600288..361fc81d4e 100644 --- a/src/Android/Avalonia.Android/Previewer/PreviewerConnection.cs +++ b/src/Android/Avalonia.Android/Previewer/PreviewerConnection.cs @@ -19,30 +19,40 @@ namespace Avalonia.Android.Previewer { internal class PreviewerConnection(PreviewPresentation previewPresentation) : IDisposable { - private IAvaloniaRemoteTransportConnection? _transport; + private IDisposable? _listener; + private IAvaloniaRemoteTransportConnection? _connection; private readonly string _sessionId = Guid.NewGuid().ToString(); public void Dispose() { - if (_transport != null) + if (_connection != null) { - _transport.OnMessage -= Transport_OnMessage; - _transport.OnException -= Transport_OnException; - _transport.Dispose(); + _connection.OnMessage -= Transport_OnMessage; + _connection.OnException -= Transport_OnException; + _connection.Dispose(); } - _transport = null; + _listener?.Dispose(); + _connection = null; + _listener = null; } [RequiresUnreferencedCode("Calls Avalonia.Remote.Protocol.BsonTcpTransport.BsonTcpTransport()")] public async void Listen(int port) { - _transport = await new BsonTcpTransport().Connect(System.Net.IPAddress.Loopback, port); - - _transport.OnMessage += Transport_OnMessage; - _transport.OnException += Transport_OnException; - - _transport.Start(); - await _transport.Send(new StartDesignerSessionMessage { SessionId = _sessionId }); + _listener = new BsonTcpTransport().Listen(System.Net.IPAddress.Loopback, port, + async t => + { + try + { + _connection = t; + _connection.OnMessage += Transport_OnMessage; + _connection.OnException += Transport_OnException; + await _connection.Send(new StartDesignerSessionMessage { SessionId = _sessionId }); + } + catch (Exception ex) + { + } + }); } private void Transport_OnException(IAvaloniaRemoteTransportConnection arg1, Exception arg2) @@ -53,7 +63,7 @@ namespace Avalonia.Android.Previewer public void Send(object obj) { - _transport?.Send(obj); + _connection?.Send(obj); } private void Transport_OnMessage(IAvaloniaRemoteTransportConnection transport, object arg2) => Dispatcher.UIThread.Post(async arg => @@ -69,11 +79,11 @@ namespace Avalonia.Android.Previewer try { await previewPresentation.UpdateXaml(xaml.Xaml); - _transport?.Send(new UpdateXamlResultMessage() { Handle = previewPresentation.View?.TopLevel?.PlatformImpl?.Handle?.ToString() }); + _connection?.Send(new UpdateXamlResultMessage() { Handle = previewPresentation.View?.TopLevel?.PlatformImpl?.Handle?.ToString() }); } catch (Exception e) { - _transport?.Send(new UpdateXamlResultMessage + _connection?.Send(new UpdateXamlResultMessage { Error = e.ToString(), Exception = new ExceptionDetails(e),