Skip to content

Commit 94027ec

Browse files
committed
🐛 Android
1 parent b7e188a commit 94027ec

File tree

8 files changed

+101
-109
lines changed

8 files changed

+101
-109
lines changed

src/Avalonia.WebView2/Controls/WebView2.Disposable.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ protected virtual void Dispose(bool disposing)
4343
// 将大型字段设置为 null
4444
#if IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW) || ANDROID
4545
viewHandler = null;
46-
platformHandle = null;
4746
#endif
4847
disposedValue = true;
4948
}

src/Avalonia.WebView2/Controls/WebView2.Methods.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ public void NavigateToString(string htmlContent)
3636

3737
public void Navigate(string uri)
3838
{
39+
_source = null;
40+
_htmlSource = null;
41+
3942
#if !DISABLE_WEBVIEW2_CORE && (WINDOWS || NETFRAMEWORK)
4043
VerifyBrowserNotCrashedGuard();
4144
CoreWebView2?.Navigate(uri);
4245
#elif ANDROID
4346
var aWebView = AWebView;
44-
if (aWebView != null)
45-
{
46-
aWebView.LoadUrl(uri);
47-
}
47+
aWebView?.LoadUrl(uri);
4848
#elif IOS || MACOS || MACCATALYST
4949
var wkWebView = WKWebView;
5050
if (wkWebView != null)

src/Avalonia.WebView2/Controls/WebView2.NativeControlHost.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ partial class WebView2
1818

1919
Handler? viewHandler;
2020

21+
static unsafe Handler CreateViewHandler(WebView2 wv2)
22+
{
23+
var createViewHandler = CreateViewHandlerDelegate;
24+
if (createViewHandler == default)
25+
{
26+
return new Handler(wv2);
27+
}
28+
else
29+
{
30+
return = createViewHandler(wv2);
31+
}
32+
}
33+
2134
///// <summary>
2235
///// For internal use by the .NET MAUI platform.
2336
///// Raised after web navigation completes.
@@ -45,7 +58,7 @@ protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle paren
4558
var parentContext = GetContext(parent);
4659
var view = CreatePlatformView(parentContext);
4760
wv2.SetValue(view);
48-
return wv2.platformHandle = new AndroidWebViewControlHandle(view, this);
61+
return this;
4962
#elif IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW)
5063
var view = CreatePlatformView();
5164
wv2.SetValue(view);

src/Avalonia.WebView2/Controls/WebView2.Properties/Source.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ public Uri? Source
3838
{
3939
throw new ArgumentException("Only absolute URI is allowed", "Source");
4040
}
41-
else if (_source == null || _source.AbsoluteUri != value.AbsoluteUri)
41+
else if (_source == null ||
42+
_source.GetType() != value.GetType() || // 允许 Uri 的派生类
43+
_source.AbsoluteUri != value.AbsoluteUri)
4244
{
4345
_htmlSource = null;
4446
SetAndRaise(SourceProperty, ref _source, value);

src/Avalonia.WebView2/Controls/WebView2.SizeChanged.cs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -175,29 +175,37 @@ protected virtual void OnWindowPositionChanged(Rectangle rectangle)
175175
_coreWebView2Controller.NotifyParentWindowPositionChanged();
176176
}
177177
#elif ANDROID
178-
var nwv = AWebView;
179-
if (nwv != null)
180-
{
181-
// https://github.com/AvaloniaUI/Avalonia/blob/11.3.1/src/Android/Avalonia.Android/AvaloniaView.cs
182-
// AvaloniaView 使用 FrameLayout 实现
183-
if (nwv.LayoutParameters is FrameLayout.LayoutParams layout)
184-
{
185-
layout.Height = rectangle.Height;
186-
layout.Width = rectangle.Width;
187-
layout.LeftMargin = rectangle.X;
188-
layout.TopMargin = rectangle.Y;
189-
nwv.LayoutParameters = layout; // 调用 java set 函数更新布局参数
190-
nwv.RequestLayout(); // 重新布局
191-
#if ANDROID && DEBUG
192-
{
193-
global::Android.Util.Log.Warn("WebView2",
194-
$"""
195-
OnWindowPositionChanged: x={rectangle.X}, y={rectangle.Y}, w={rectangle.Width}, h={rectangle.Height}
196-
""");
197-
}
198-
#endif
199-
}
200-
}
178+
// var nwv = AWebView;
179+
// if (nwv != null)
180+
// {
181+
// // https://github.com/AvaloniaUI/Avalonia/blob/11.3.1/src/Android/Avalonia.Android/AvaloniaView.cs
182+
// // AvaloniaView 使用 FrameLayout 实现
183+
// if (nwv.LayoutParameters is FrameLayout.LayoutParams layout)
184+
// {
185+
// layout.Height = rectangle.Height;
186+
// layout.Width = rectangle.Width;
187+
// layout.LeftMargin = rectangle.X;
188+
// layout.TopMargin = rectangle.Y;
189+
// nwv.LayoutParameters = layout; // 调用 java set 函数更新布局参数
190+
// nwv.RequestLayout(); // 重新布局
191+
//#if ANDROID && DEBUG
192+
// {
193+
// var isUIThread = Dispatcher.UIThread.CheckAccess();
194+
// var isUIThreadA = (int)global::Android.OS.Build.VERSION.SdkInt >= 23 ?
195+
//#pragma warning disable CA1416 // 验证平台兼容性
196+
// global::Android.OS.Looper.MainLooper!.IsCurrentThread :
197+
//#pragma warning restore CA1416 // 验证平台兼容性
198+
// (global::Android.OS.Looper.MainLooper!.Thread == global::Java.Lang.Thread.CurrentThread());
199+
// global::Android.Util.Log.Warn("WebView2",
200+
// $"""
201+
//OnWindowPositionChanged: x={rectangle.X}, y={rectangle.Y}, w={rectangle.Width}, h={rectangle.Height}
202+
//isUIThread: {isUIThread}
203+
//isUIThreadA: {isUIThreadA}
204+
//""");
205+
// }
206+
//#endif
207+
// }
208+
// }
201209
#elif IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW)
202210
var nwv = WKWebView;
203211
// TODO: 将 xywh 矩阵值传递给本机控件,CGRect 使用浮点型,疑似逻辑值,而不是物理像素值,需要计算 DPI 缩放?

src/Avalonia.WebView2/Controls/WebView2.VisualTree.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,11 @@ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
7070
TopLevel = topLevel;
7171
}
7272
#if ANDROID
73-
if (IsVisible)
73+
if (viewHandler == null)
7474
{
75-
var nwv = AWebView;
76-
if (nwv != null)
77-
{
78-
if (nwv.Visibility != global::Android.Views.ViewStates.Visible)
79-
{
80-
nwv.Visibility = global::Android.Views.ViewStates.Visible;
81-
}
82-
}
75+
{
76+
viewHandler = CreateViewHandler(this);
77+
Child = viewHandler;
8378
}
8479
#elif IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW)
8580
if (IsVisible)

src/Avalonia.WebView2/Controls/WebView2.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,6 @@ public WebView2()
3737
#if !(WINDOWS || NETFRAMEWORK) && NET8_0_OR_GREATER && !ANDROID && !IOS && !MACOS && !MACCATALYST && !DISABLE_CEFGLUE
3838
//CefGuleInitialize();
3939
#endif
40-
41-
#if IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW) || ANDROID
42-
unsafe
43-
{
44-
var createViewHandler = CreateViewHandlerDelegate;
45-
if (createViewHandler == default)
46-
{
47-
viewHandler = new Handler(this);
48-
}
49-
else
50-
{
51-
viewHandler = createViewHandler(this);
52-
}
53-
}
54-
Child = viewHandler;
55-
#endif
5640
}
5741

5842
#if IOS || MACCATALYST || (MACOS && !USE_DEPRECATED_WEBVIEW) || ANDROID

src/Avalonia.WebView2/Platforms/Droid/Controls/WebView2.cs

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Android.Graphics;
44
using Android.Graphics.Drawables;
55
using Android.OS;
6+
using Android.Runtime;
67
using Android.Views;
78
using Android.Webkit;
89
using AndroidX.Core.View;
@@ -24,8 +25,6 @@ partial class WebView2
2425
/// </summary>
2526
partial class Handler
2627
{
27-
public AWebView? PlatformView => wv2.platformHandle?.WebView;
28-
2928
protected virtual WebViewClientCompat CreateWebViewClient() => new WebViewClientCompat2(this);
3029

3130
protected virtual WebChromeClient CreateWebChromeClient() => new WebChromeClient2(this);
@@ -85,25 +84,64 @@ public virtual void DisconnectHandler(AWebView platformView)
8584
}
8685
}
8786

87+
partial class Handler : IPlatformHandle, INativeControlHostDestroyableControlHandle
88+
{
89+
nint IPlatformHandle.Handle => webView == default ? default : webView.Handle;
90+
91+
string? IPlatformHandle.HandleDescriptor => "android.view.View";
92+
93+
bool disposedValue;
94+
protected AWebView? webView;
95+
96+
protected bool DisposedValue => disposedValue;
97+
98+
public AWebView? PlatformView => webView;
99+
100+
void Dispose(bool disposing)
101+
{
102+
if (!disposedValue)
103+
{
104+
if (disposing)
105+
{
106+
// 释放托管状态(托管对象)
107+
if (webView != null)
108+
{
109+
DisconnectHandler(webView);
110+
webView.Destroy(); // 销毁平台控件
111+
webView.Dispose();
112+
}
113+
}
114+
115+
// 释放未托管的资源(未托管的对象)并重写终结器
116+
// 将大型字段设置为 null
117+
webView = null;
118+
disposedValue = true;
119+
}
120+
}
121+
122+
/// <inheritdoc/>
123+
public void Destroy()
124+
{
125+
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
126+
Dispose(disposing: true);
127+
}
128+
}
129+
88130

89131
public static Context? GetContext(IPlatformHandle platformHandle)
90132
{
91133
if (platformHandle is AndroidViewControlHandle viewControlHandle)
92134
{
93135
return viewControlHandle.View?.Context;
94136
}
95-
else if (platformHandle is AndroidWebViewControlHandle webView2ControlHandle)
96-
{
97-
return webView2ControlHandle.WebView?.Context;
98-
}
99137
return null;
100138
}
101139

102140
public AWebView? AWebView
103141
{
104142
get
105143
{
106-
var result = platformHandle?.WebView;
144+
var result = viewHandler?.PlatformView;
107145
if (result.IsAlive())
108146
{
109147
return result;
@@ -112,8 +150,6 @@ public AWebView? AWebView
112150
}
113151
}
114152

115-
AndroidWebViewControlHandle? platformHandle;
116-
117153
protected virtual void SetValue(AWebView webView)
118154
{
119155
if (_source != null)
@@ -245,51 +281,6 @@ public void LoadDataWithBaseURL(AWebView webView)
245281
}
246282
}
247283

248-
sealed class AndroidWebViewControlHandle : PlatformHandle, INativeControlHostDestroyableControlHandle
249-
{
250-
bool disposedValue;
251-
AWebView? webView;
252-
WebView2.Handler? handler;
253-
254-
internal AndroidWebViewControlHandle(AWebView webView, WebView2.Handler handler) : base(webView.Handle, "android.webkit.WebView")
255-
{
256-
this.webView = webView;
257-
this.handler = handler;
258-
}
259-
260-
public AWebView? WebView => webView;
261-
262-
void Dispose(bool disposing)
263-
{
264-
if (!disposedValue)
265-
{
266-
if (disposing)
267-
{
268-
// 释放托管状态(托管对象)
269-
if (webView != null)
270-
{
271-
handler?.DisconnectHandler(webView);
272-
webView.Destroy(); // 销毁平台控件
273-
webView.Dispose();
274-
}
275-
}
276-
277-
// 释放未托管的资源(未托管的对象)并重写终结器
278-
// 将大型字段设置为 null
279-
webView = null;
280-
handler = null;
281-
disposedValue = true;
282-
}
283-
}
284-
285-
/// <inheritdoc/>
286-
public void Destroy()
287-
{
288-
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
289-
Dispose(disposing: true);
290-
}
291-
}
292-
293284
static class JavaObjectExtensions
294285
{
295286
public static bool IsDisposed(this global::Java.Lang.Object obj)

0 commit comments

Comments
 (0)