C# MAUI平台特定代码方法 C#如何调用Android和iOS原生API

来源:这里教程网 时间:2026-02-21 17:40:55 作者:

Platform-agnostic调用原生API必须走
Microsoft.Maui.Controls.Handlers.Compatibility
吗?

不需要。MAUI 从 6.0 开始已弃用兼容层,所有平台特定代码应通过

Microsoft.Maui.Platform
(Android)和
Microsoft.Maui.Platforms.iOS
(iOS)中的扩展方法或自定义处理程序实现。直接引用旧兼容命名空间会导致编译失败或运行时异常。

正确路径是:在

Platforms/Android
Platforms/iOS
目录下编写平台专属代码,利用 MAUI 的依赖注入机制或
DeviceInfo
/
MainThread
等跨平台抽象做桥接。

Android端调用
Activity
Context
常见报错和绕过方式

在 Android 平台代码中,直接访问

CurrentActivity
ApplicationContext
时容易遇到
NullReferenceException
——尤其在启动早期(如
App.xaml.cs
构造函数中)或后台线程里。

MauiApplication.Current?.Windows.FirstOrDefault()?.Handler?.MauiContext?.Context
是较稳妥的 Context 获取路径,但需确保窗口已初始化
若需在 Activity 生命周期回调中操作(如
OnResume
),应继承
Microsoft.Maui.MauiApplication
并重写
OnCreate
,再通过
RegisterActivityLifecycleCallbacks
注册监听
避免在非 UI 线程直接调用
Toast.MakeText
等 UI 方法;改用
MainThread.InvokeOnMainThreadAsync
包裹

iOS端访问
UIApplication
UIViewController
的时机陷阱

iOS 上最常踩的坑是过早访问

UIApplication.SharedApplication.KeyWindow?.RootViewController
—— MAUI 启动完成前该值为
null
,且 iOS 15+ 后
KeyWindow
已被弃用。

推荐使用
MauiUIApplicationDelegate.Window
(在
Platforms/iOS/AppDelegate.cs
中可安全获取)作为根视图控制器来源
若需在页面级调用原生 API(如弹出
UIAlertController
),应在
OnAppearing
中延迟一小段(
await Task.Delay(1)
)再获取
UIViewController
,或通过
IVisualElementRenderer
ViewController
属性取当前页控制器
注意:iOS 所有 UI 操作必须在主线程,
DispatchQueue.MainQueue.DispatchSync
是必需的,不能省略

如何安全暴露原生能力给共享项目(C#逻辑层)

不能让共享项目直接引用

Android.App.Activity
UIKit.UIViewController
,否则破坏平台隔离。标准做法是定义接口 + 平台实现 + DI 注册。

例如定义

IFilePickerService
接口,然后:

Android 实现类中用
ActivityResultLauncher
启动文件选择器,并通过
TaskCompletionSource
封装为异步方法
iOS 实现类中用
UIDocumentPickerViewController
,在
DidPickDocumentAtUrls
回调中设置
TCS.SetResult
MauiProgram.CreateMauiApp()
中注册:
builder.Services.AddSingleton<ifilepickerservice filepickerservice>()</ifilepickerservice>
(平台项目中条件注册)

关键点:所有原生类型(

Intent
NSUrl
)必须在平台实现内部转换为跨平台模型(如
string
路径或
Stream
),不泄露任何平台特有类型到共享层。

相关推荐