ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VS2019 + C# + Xamarin.Forms:用C#开发Android手机App实战指南

VS2019 + C# + Xamarin.Forms:用C#开发Android手机App实战指南 很多人一听“VS2019 C# 开发手机App”第一反应是C#不是写Windows桌面程序的吗怎么跟手机沾边我以前做上位机、写WinForms写了好几年第一次被问到能不能用C#做一个手机端数据查看App的时候也愣了一下。但你如果打开VS2019的安装器认真翻一遍工作负载会发现里面赫然躺着一个“使用.NET的移动开发”这就是微软官方给出的路Xamarin.Forms。这篇文章就是把我实际配环境、写页面、调接口、真机部署的整个过程拆开来讲。适合谁看呢比如你已经用C#写了好几年上位机或后端服务现在想把数据搬到手机上看或者你是个刚入门.NET的初学者不想再从Java/Kotlin学起就想用C#先做一个能跑的Android App。这篇文章都能帮你把整条路走通。我会直接说结论、给配置、贴代码也会把那些文档里不写、只有踩过坑才知道的细节全交代清楚。1. 路线选型到底走哪条路别上来就装错东西1.1 为什么是 Xamarin.Forms先说原理不然你后面配环境都会稀里糊涂。Xamarin.Forms 是微软在收购 Xamarin 之后深度集成到 Visual Studio 里的跨平台UI框架。它的核心思路是你用 C# 写业务逻辑用 XAML 写界面这套代码可以同时编译成 Android 和 iOS 两个平台的原生应用。Android 端最终产出 APKiOS 端产出 IPA。它底层的运行机制不是类似浏览器套壳那种WebView渲染而是通过 Mono 运行时把 C# 代码跑在移动设备的原生环境里UI控件最终映射成 Android 的 View 或 iOS 的 UIView。这意味着什么意味着你以前在 WinForms / WPF 里写的数据处理、串口解析、HTTP调用、JSON序列化这一大堆代码可以直接搬到移动端里继续用。你不需要为了手机App去学 Kotlin 或者 Swift语言层面零切换。我看到很多人一上来就纠结“Xamarin.Forms是不是被微软抛弃了”。这里要说清楚微软确实已经推出了新一代跨平台方案 .NET MAUIVS2022 直接用Xamarin.Forms 进入了维护模式。但如果你手里的电脑装的是 VS2019或者公司内网、工控机环境锁死了 VS 版本Xamarin.Forms 依然是最顺、最稳的选择。我做项目到现在Xamarin.Forms 4.x/5.x 的老工程仍然在正常维护、正常打包上架并没有“不能用了”这回事。1.2 主流开发路线横向对比我把目前能接触到的几条路线放在一个表里大家自己对照方案语言VS2019支持适用场景主要短板Xamarin.FormsC# / XAML原生支持.NET团队跨平台快速出App新项目官方已转向MAUI.NET MAUIC# / XAML不支持需VS2022新项目首选需要升级开发工具Blazor HybridC# / Web不支持需VS2022偏Web技术栈团队最终也是新工具链Android原生Kotlin/Java支持但语言无关高性能、体验要求高要单独学语言iOS原生Swift需Mac环境上架App Store要Mac、要学SwiftFlutterDart需扩展跨平台UI一致性强脱离C#生态React NativeJavaScript/TS需扩展前端团队做App桥接层有性能损耗UnityC#支持游戏类App不适合业务型App从这个表能看出来VS2019 环境下想用 C# 做通用业务型 App只有一个正确答案Xamarin.Forms。这不是“最好的方案”但在“VS2019 C# 手机App”这三个约束同时成立的情况下它就是最务实的方案。1.3 这套方案的现实定位与适合人群我用下来最大的感受是Xamarin.Forms 特别适合“工具型App”和“企业内部App”。什么叫工具型比如你是做设备数据采集的现场有个设备通过串口转WiFi把数据发到服务器你需要手机端能实时查几台设备的状态、看曲线、收报警。这种业务逻辑清晰、UI不需要太炫、只需要把数据正确展示的AppXamarin.Forms 做起来效率非常高。什么叫企业内公司内部审批、报表查看、库存查询目标用户就那几十上百人不需要上架各大应用商店直接给个 APK 装到手机里就完事。这种项目用 C# 快速交付成本极低。但如果你的目标是做一个面向普通消费者的C端应用追求极致流畅的动画和交互体验那我建议你还是认真评估一下 Flutter 或原生开发。Xamarin.Forms 在这方面的确比不过原生方案这是它的定位决定的不是技术差而是取舍。2. 环境配置从空电脑到模拟器跑通2.1 VS2019 安装工作负载这一步很多人栽了跟头装 VS2019 的时候默认安装只带基础的 .NET 桌面开发你装完发现根本建不了移动App项目。正确的操作是打开 Visual Studio Installer在“工作负载”里勾选那个叫“使用.NET的移动开发”的选项它里面包含了 Xamarin SDK、Android SDK 相关工具链、Android 模拟器组件。这里有几个细节要注意社区版Community是免费的官方许可允许个人开发者、小型团队使用不需要什么产品密钥。网上到处搜“vs2019产品密钥”多半是没搞清楚版本策略。工作负载勾选后安装体积会变大不少磁盘预留至少 20GB 比较稳。如果你在内网、离线环境工作可以用vs_enterprise.exe --layout 目录先在一台能上网的机器上下载离线安装包再拷贝到内网机器安装。这个包非常大动辄二三十GB但确实能解决内网没网装不了的问题。安装完成后打开 VS2019在菜单栏能看到“工具 Android”这两个字说明 Xamarin 组件已经到位了。如果看不到大概率是工作负载没勾上。别忽视这步。我见过好几个同事装了VS2019好久某天突然说“我C#怎么不能新建Android项目”结果一查就是当初装的时候没勾移动开发工作负载。2.2 JDK 与 Android SDK 的版本匹配最容易报错的地方如果你是从 Windows 桌面开发转到移动端第一次跑 Xamarin.Forms 的 Android 项目时极大概率会在编译阶段看到一串Java相关的红色报错。核心原因就是 JDK 版本和 Android SDK 版本不匹配。Xamarin 对 JDK 版本的依赖非常严格不是说你机器上有 Java 就行。我这里给出一份当前还算通用的匹配参考项目推荐版本说明JDK1164位VS2019 16.4 对 Android API 30/31 的常见要求JDK 8老项目兼容用一些远古 SDK 或 Gradle 版本强制要求Android SDK PlatformAPI 30 / 31对应 Android 11 / 12兼容性和稳定性较好Android SDK Build-Tools30.0.3 / 31.0.0版本太旧会出 aapt2 编译失败配置界面在 VS2019 菜单栏工具 选项 Xamarin Android Settings。把 JDK 路径和 Android SDK 路径都指向你实际安装的位置。我踩过的坑主要有这几个JDK 装了 32 位版本VS 直接提示找不到 64 位 JDK。现在新机器基本是64位系统一定要下jdk-11.0.x_windows-x64_bin.exe这种 x64 版本。JDK 路径带了中文或空格导致 Gradle 脚本解析失败。最好装在C:\Program Files\Java\jdk-11或者干脆D:\jdk11这种干净路径下。Android SDK 在不同盘符VS 自动探测不到需要手动填路径。填完之后重启 VS 才生效。还有一个隐藏较深的问题有些机器以前装过 Android Studio环境变量JAVA_HOME指向的是 JDK 8VS 会优先读这个环境变量导致你明明装了 JDK 11 却依然报版本过低。遇到这种情况直接把JAVA_HOME改成 JDK 11 的路径再重启 VS。2.3 模拟器选型与真机调试准备模拟器这块新手最容易纠结。用哪个怎么这么慢为什么启动黑屏我直接给结论。VS2019 自带的 Android 模拟器Visual Studio Emulator for Android能用但管理功能比较弱机型配置也少。更顺手的是装一个 Android Studio用它的 AVD Manager 创建模拟器。你不要怕“我不用Android Studio写代码是不是装了它没意义”不冲突你只是借用它的模拟器管理器和 SDK 管理器写代码还是回 VS2019。创建模拟器时选镜像有一点讲究x86_64 的镜像配合 Intel HAXM 或 Windows Hyper-V跑起来速度基本可接受。ARM 镜像在 x86 电脑上是通过软件翻译跑的慢到你怀疑人生不推荐。模拟器慢的根源在于它在你的 Windows 系统里模拟了一整套 Android 系统冷启动要加载内核、启动服务第一次跑个三五分钟非常正常。我实际操作中发现一个提升体验的小技巧模拟器不要频繁关闭让它一直在后台挂着后续每次部署只增量安装 APK体感会快很多。真机调试往往比模拟器更省心。Android 手机上开启“开发者选项”步骤是设置 关于手机 连按“版本号”七次然后进入 设置 系统 开发者选项打开“USB调试”。插上 USB 线后手机弹窗问是否允许 USB 调试点允许。电脑端如果提示安装驱动用设备管理器找到带黄色感叹号的设备手动更新驱动通常安装手机厂商提供的 USB 驱动就行。如果你电脑离手机远还可以走无线调试。Android 11 及以上在开发者选项里直接开“无线调试”用adb pair配对即可。老版本可以先用 USB 执行一次adb tcpip 5555拔线后用adb connect 手机IP:5555连上。这对调试那种“设备在现场、人在办公室”的场景很实用。2.4 抓包调试的前置准备Fiddler 抓手机 App 请求做 App 开发联调接口是日常操作。你不抓包光靠代码里打日志效率极低。Fiddler 是我最常用的调试抓包工具专门用来把手机的 HTTP/HTTPS 请求镜像到电脑上查看。基本的操作思路电脑上打开 Fiddler在 Tools Options HTTPS 里勾选 Decrypt HTTPS traffic让 Fiddler 能解开 HTTPS 内容然后在 Fiddler 的 Connections 里确认监听端口默认是 8888。手机和电脑连同一个局域网手机 WiFi 设置里把代理改成手动服务器写电脑的局域网 IP端口写 8888。此时手机上的流量就会经过 Fiddler你在 Fiddler 里能看到每个请求的 URL、请求头、请求体、响应体排查接口问题一目了然。但有一个新版 Android 特有的坑得重点讲Android 7.0 及以上App 默认只信任系统证书不信任用户安装的 CA 证书。所以就算你手机安装了 Fiddler 的根证书抓包时 HTTPS 请求依然会失败或显示证书错误。解决办法是在 App 的 Android 工程里配置网络安全策略允许调试时信任用户证书。具体做法是在Resources/xml下新建一个network_security_config.xml然后在 AndroidManifest.xml 的application节点引用它。这个属于开发期配置正式发布时可以收紧回去。3. 实战开发从空项目到能连接口的 App3.1 新建项目先搞懂工程结构再动代码打开 VS2019新建项目搜索 Xamarin选择“移动应用 (Xamarin.Forms)”这个模板。弹出的对话框里会让你选择应用模板有两个选项Shell 和 Blank。Shell 模板会生成一个带导航框架的 App自带底部导航、导航栏这类结构适合多页面、有切换需求的业务应用。Blank 模板是干净的空白页适合你自己控制布局和导航。我一般做工具型App喜欢选 Shell因为省去自己搭导航的功夫。创建完成后你会看到解决方案里有多个项目一个共享代码库项目通常是 .NET Standard 2.0后缀可能叫.Shared或直接是主项目。你有没有页面、业务逻辑、HTTP 访问、数据模型全部写在这个项目里。一个 Android 头工程名字带.Android负责生成 Android APK。AndroidManifest.xml、Android 资源、权限配置都在这。一个 iOS 头工程名字带.iOS。你没有 Mac 的情况下可以先不管甚至可以在项目属性里禁用 iOS 编译也不用删除反正 Windows 上编不了 iOS。这结构乍一看有点一头雾水实际上套壳思路共享库是核心大脑Android 和 iOS 是两副躯壳。你要做的就是让共享库里的代码尽量写得多多的头工程里的代码尽量写得少少的。3.2 用 XAML 搭界面用 C# 写逻辑XAML 语法如果你写过 WPF上手零成本。这里我举一个实际例子一个最简单的登录界面上半部分。ContentPage xmlnshttp://xamarin.com/schemas/2014/forms xmlns:xhttp://schemas.microsoft.com/winfx/2009/xaml x:ClassMyApp.LoginPage StackLayout Padding30 VerticalOptionsCenter Label Text用户名 FontSize14 / Entry x:NametxtUser Placeholder请输入用户名 / Label Text密码 FontSize14 / Entry x:NametxtPwd IsPasswordTrue Placeholder请输入密码 / Button x:NamebtnLogin Text登录 ClickedBtnLogin_Clicked / Label x:NamelblStatus Text HorizontalTextAlignmentCenter TextColorRed / /StackLayout /ContentPage对应的事件处理在 C# 代码里private async void BtnLogin_Clicked(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(txtUser.Text) || string.IsNullOrWhiteSpace(txtPwd.Text)) { lblStatus.Text 用户名和密码不能为空; return; } lblStatus.Text 正在登录...; // 这里调用你封装好的 HTTP 接口见 3.3 节 var success await LoginService.LoginAsync(txtUser.Text, txtPwd.Text); lblStatus.Text success ? 登录成功 : 用户名或密码错误; }实际项目里我建议你尽早引入 MVVM 思想把逻辑从页面代码后置里剥离出去比如用BindingContext绑定一个 ViewModel。但新手前期不用一上来就套上 Prism 这种重型框架纯 Code-behind 把功能跑通之后再逐步把属性绑定、命令绑定这些概念加进去理解会更深。XAML 的核心价值在于把界面结构和逻辑分开就像做菜时把食材准备和烹饪步骤分开一样。你改界面布局的时候不用动 C# 逻辑改逻辑的时候不用去一堆嵌套的界面代码里找方法后续维护体验完全不是一个级别。3.3 对接 HTTP 接口HttpClient 与 Android 明文流量限制手机App几乎都要联网。C# 里最直接的 HTTP 客户端就是HttpClient。比如你后端有一个登录接口using System.Net.Http; using Newtonsoft.Json; public static class LoginService { private static readonly HttpClient client new HttpClient(); public static async Taskbool LoginAsync(string user, string pwd) { var body new { username user, password pwd }; var json JsonConvert.SerializeObject(body); var content new StringContent(json, System.Text.Encoding.UTF8, application/json); var resp await client.PostAsync(http://192.168.1.100:8080/api/login, content); if (!resp.IsSuccessStatusCode) { return false; } var respJson await resp.Content.ReadAsStringAsync(); var result JsonConvert.DeserializeObjectLoginResult(respJson); return result?.Success ?? false; } }这段代码看着很常规但如果你直接跑在 Android 9 及以上系统的手机里大概率会抛一个异常内容类似Cleartext HTTP traffic to 192.168.1.100 not permitted。这是 Android 出于安全考虑默认禁止应用发送不加密的 HTTP 明文流量。解决办法有两个一是暴力解法在 Android 工程的 AndroidManifest.xml 的application节点里加一句application android:usesCleartextTraffictrue ...二是规范解法配置网络安全策略指定哪些域名允许明文流量。在Resources/xml/network_security_config.xml里写?xml version1.0 encodingutf-8? network-security-config domain-config cleartextTrafficPermittedtrue domain includeSubdomainstrue192.168.1.100/domain /domain-config /network-security-config然后在 AndroidManifest.xml 里引用application android:networkSecurityConfigxml/network_security_config ...实际开发调试阶段图省事用第一种快正式交付前建议改成第二种精确控制域名避免平白暴露安全风险。3.4 真机部署、签名与发布成本开发阶段调试直接把手机用 USB 连上电脑在 VS2019 里把运行目标选成你的手机型号按 F5 就能把应用部署到手机里。这时候应用跑的是 Debug 包能看到 VS 输出窗口里的调试日志也能打断点。要给别人安装或准备上架应用市场就必须打 Release 签名包。Android 普及签名机制APK 必须用证书签名才能安装Debug 包用的是系统自动生成的调试证书Release 包推荐自己生成一个正式证书。VS2019 里可以通过项目属性 Android 包签名来生成和配置签名文件。签名证书一定要备份好应用后续更新必须用同一个证书签名丢了证书意味着你再也无法更新这个App了。顺便说一句很多人问的上架成本问题。开发一个 App 并上架大概要多少钱这没有一个固定答案它取决于你要上哪些市场。Google Play 开发者账号是 25 美元一次性注册App Store 是 99 美元一年而且还得有 Mac国内部分安卓市场要求软著、企业资质这个成本就比较复杂甚至比开发本身更费精力。如果只是公司内部使用不走商店那成本基本就是开发工时证书自己生成APK 发到群里让大家安装就行。4. 问题排查与经验总结4.1 版本兼容VS2015、VS2019 与库的兼容真相我经常被问到两个版本类问题这里统一回答。第一个问题“用 VS2019 开发的 C# 上位机源码程序能用 VS2015 打开吗”答案是分情况。如果那个上位机项目是纯粹的 .NET Framework 类库或 WinForms 工程目标框架是 4.x而且代码没有用到 C# 7.0 及更高版本的语法VS2015 大概率能打开。但如果代码里用了$字符串插值、out var、模式匹配这类新语法VS2015 的编译器不认识就会报诡异错误。所以能不能打开取决于“工程文件格式”和“C# 语言版本”两个维度不能一句话打包票。第二个问题“VS2019 创建的 Xamarin.Forms 工程能用 VS2015 打开吗”这个基本不用指望。Xamarin.Forms 项目基于 .NET Standard 2.0VS2015 对 .NET Standard 的支持非常有限而且 VS2015 自带的 Xamarin 工具链版本太老打开新格式工程大概率直接失败。遇到这种情况要么统一开发工具版本要么把共享代码抽出来控制成兼容的 .NET Framework 库作为折中。4.2 模拟器与部署问题速查我把平时遇到频率最高的几个问题整理成了表方便你对照排查问题现象常见原因解决办法模拟器启动后一直黑屏冷启动需要时间显卡驱动不兼容耐心等3-5分钟更新显卡驱动换真机测试模拟器非常卡电脑没有开启 Hyper-V 或 WHPX 加速BIOS 开启虚拟化Windows 功能启用 Hyper-Vadb 提示 device unauthorized手机上未确认授权弹窗拔线重插手机上勾选“始终允许”部署时报错 APK 安装失败手机上已装同签名不同名的旧包先卸载旧 App 再部署Fiddler 抓不到 App 的包Android 7.0 不信任用户证书按 2.4 节配置 networkSecurityConfig还有一个容易被忽略的坑adb 的 5037 端口被其他程序占用了连真机时 VS 输出窗口报 adb 错误。解决办法是打开任务管理器结束占用该端口的进程或者在命令行执行adb kill-server然后adb start-server。4.3 Debug 与性能卡顿、断点不生效的排查思路先聊断点不生效。最常见的场景是一顿操作猛如虎断点一打是虚的代码根本没命中。排查顺序确认当前是 Debug 而不是 Release确认项目配置里开启了“优化代码”未勾选确认你改的是共享库里的代码而不是 Android 头工程里的代码。如果共享库里命中断点却看不到局部变量值先让代码走几步刷新状态不要一上来就怪 VS。再聊 ListView 卡顿。我用 Xamarin.Forms 做过查询列表数据量一上五百条ListView 滑动就开始掉帧。优化方向给 ListView 设置CachingStrategyRecycleElement这是最有效的一招让行视图复用而不是无限创建。图片列表用到Image控件时不要再直接绑定原始大图 URL务必做缩略图。如果列表极其复杂考虑换成CollectionView它比 ListView 在性能和扩展性上都好得多。调试阶段在模拟器里卡没问题但真机上如果依然卡成 PPT那问题就出在你自己的代码上了老老实实去看哪些地方阻塞了 UI 线程。记住一句话移动 UI 线程永远不要做耗时操作耗时操作一律走异步。最常见的大坑是await写漏了方法标记了 async 但里面某一步忘了 await导致接口响应期间界面直接卡死。4.4 绕开弯路给新手和跨方向朋友的建议有几个热搜词来看很多人可能同时在看 Python 环境配置、Vue 安装、Node 环境这些完全不同的技术栈。我多说一句移动开发的环境配置跟 Python、Node、Vue 那套完全是两套玩法别混着学。Xamarin 的环境依赖链是 Visual Studio 工作负载 JDK Android SDK 这三者的精确配合你在这上面花时间不算亏但别指望用装 Python 包的心态去搞定 Android 工具链。如果你是纯新手连 C# 基础语法还不够熟练我建议先别急着做 App。先在 Windows 控制台项目里把循环、类、接口、集合这些基础跑熟再用 WinForms 做一两个小工具练手最后再进移动端。步子太大你分不清问题是出在 C# 还是出在 Xamarin 上。如果你看完这些觉得“这也不是很难”那恭喜你你已经具备了用 C# 开发手机 App 的基本认知了。剩下的就是动手敲一点一点把一个能连接口、能查数据的小 App 跑起来这个过程比看二十篇文章都管用。我在实际项目里最大的体会是VS2019 Xamarin.Forms 这套组合论新潮它比不过 MAUI、Flutter但它依然是 C# 存量工程师切入移动端门槛最低的一条路。核心逻辑可以复用工具链是 VS 自己带模拟器、抓包、断点调试这些流程链路上也都能走通。对于那些公司内部工具、工业数据监控、简单业务流转这类App它完全够用而且交付效率真的高。最后分享一个我自己的小习惯动手写 Xamarin 界面之前我先把核心业务逻辑在控制台项目里验证一遍比如接口返回的数据结构、解析是否正常、异常分支怎么处理。等这些逻辑全部确认无误再套上 Xamarin 的壳去写页面。这样排错范围会大大缩小你也不会在前端UI的地狱里抓瞎整个下午。反正代码是同一套 C#验证完逻辑再做界面能帮你在移动端调试这条路上省下大量时间。
返回列表