概述

  上一篇 C#移动跨平台开发(1)环境准备发布之后不久,无独有偶,微软宣布了开放.NET框架源代码并且会为Windows、Mac和Linux开发一个核心运行时(Core CLR),这也是开源的!IT媒体网站纷纷转载,博客园的C#开发者们热泪盈眶(泥煤都等这一天好久了!)

  与此同时VS2015预览版更是直接集成了Android模拟器,但是其实里面并没有说集成IOS模拟器,我不知道大家是怎么得出可以直接用VS来开发Android和IOS应用的。不管怎么说,这都是个好消息。那么问题来了,C#如何来开发Android和IOS应用?微软会怎么做我们不确定,但是我们倒是可以来看看Xamarin是如何做的。

Android系统架构

  我想下面这张图做Android开发的同学应该很熟悉,下面我们就通过来了解Android系统的架构入门来看看Xamarin会怎么样去做?

  • Linux Kernel 操作系统层
  • Libraries And Android Runtime 各种库和Android 运行环境
  • Application Framework 应用框架层 (由Java编写)
  • Applications 应用程序层(由Java编写并且在Dalvk虚拟机来运行)

  现在做Android开发的同学只要熟悉这些应用框架层的一些接口和类库就可以给方便的来实现自己的Android应用程序。

关于Dalvk虚拟机与Java运行环境的区别

  1. Dalvik主要是完成对象生命周期管理,堆栈管理,线程管理,安全和异常管理,以及垃圾回收等等重要功能。
  2. Dalvik负责进程隔离和线程管理,每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
  3. 不同于Java虚拟机运行java字节码,Dalvik虚拟机运行的是其专有的文件格式
  4. Dex文件格式可以减少整体文件尺寸,提高I/o操作的类查找速度。
  5. 是为了在运行过程中进一步提高性能,对dex文件的进一步优化。
  6. 所有的Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
  7. 有一个特殊的虚拟机进程Zygote,他是虚拟机实例的孵化器。它在系统启动的时候就会产生,它会完成虚拟机的初始化,库的加载,预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的数据提供给系统。对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域。

  大家注意第2点和第7点有助于我们理解Xamarin.Android的工作机制。

Xamarin.Android 架构

  Java编写的Android应用程序通过调用 Android.* 和 Java.* 这些命名空间下的类来实现一些系统的功能包括:声音、显示、OpenGl等一些通过Java API不能实现的功能或者说是与硬件、系统平台相关的功能。那这里的问题是当我们用C#来编写的时候,这些功能怎么去调用?C#写的Android 应用程序又是如何初始化的?

Android Callable Wrappers (ACW)

  当一个C#开发的Android程序运行的时候,除了一个Dalvik的虚拟机实例,还有一个Mono的虚拟机实例在运行。那个Dalvik虚拟机实体就像一个宿主,我们的APP在宿主上运行,而我们所有用C#写的方法都会以ACW的形式被调用。在Java代码中以native的式式invoke,就像invoke其它C或者C++的代码一样。

  Momodroid.exe 在编译阶段会为我们的C#类生成对应的ACW。

 using System;
using Android.App;
using Android.OS; namespace Mono.Samples.HelloWorld
{
public class HelloAndroid : Activity
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (R.layout.main);
}
}
}

对应生成的ACW代码:

 package mono.samples.helloWorld;

 public class HelloAndroid
extends android.app.Activity
{
static final String __md_methods;
static {
__md_methods =
"n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler\n" +
"";
mono.android.Runtime.register ("Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", HelloAndroid.class, __md_methods);
} public HelloAndroid ()
{
super ();
if (getClass () == HelloAndroid.class)
mono.android.TypeManager.Activate ("Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] { });
} @Override
public void onCreate (android.os.Bundle p0)
{
n_onCreate (p0);
} private native void n_onCreate (android.os.Bundle p0);
}

  大家可以看到上面那个 native的n_onCreate方法最后就会调用那个通过mono虚拟机注册的Mono.Samples.HelloWorld.OnCreate 方法。

Managed Callable Wrappers (MCW)

  上面我们讲Dalvik 虚拟机是我们C#开发的Android应用程序的宿主,它通过ACW来调用我们用C#写的方法。如果我们的这个C#里面的方法涉及到一些声音或者系统本身,或者说现在已经有很多成熟的用Java写的类库,我们想调用怎么办? 答案是我们再通过MCW 调回去。在C#运行时中去调用Java 称之为MCW。

  Xamarin.Android Framework中有很多就是MCW,关于MCW的创建以及C#与Java集成开发的东西我们后面再细讲,包括一个C#开发的Android应用程序是如何被启动的,我们后面再细讲。对于C#开发的Android应用程序来说,性能上面肯定是会有影响,但是影响有多大,我并没有做过具体测试,所以就不详述了。后面我们再细细的去对比。

Xamarin.IOS 架构

  对于开发者来说,Xamarin.IOS相对于Xamarin.Android就要简单很多了,我们用C#开发的ios应用程序在被编译成IL代码之后,然后转交给Apple complier直接编译成IPhonee的本地机器码。也就是说C#写的IPhone应用程序和objective-c 写的是一样的。并且Xamarin团队保证在每一个IOS系统更新的时间同步更新Xamarin.IOS这样我们就不用担心被滞后了。

小结

  这仅仅是一个粗略的介绍,Xamarin移动跨平台方案是如何来工作的,还有太多我们没有涉及。 Xamarn.Forms为多种移动平台提供了统一的UI(虽然目前还有些比较特别的没有实现,官方也没有力推它,用来做一些原型,或者概念验证可以试一样,另外如果你的UI确实很简单,那倒是没有问题。),当然在Xamarin.Forms不能够满足你的要求的时候,可以使用Xamarin.Android和Xamarin.IOS的UI控件,这些也是Native的,也就是说在UI方面不会有性能的影响。

  就目前来看C#来开发IOS应用更具有优越性,我们要在VS中开发Iphone的应用程序需要配一台Mac来做编译。相对而言,开发Android的应用程序就会显得繁琐一些,底下还有一些隐藏的东西我们没有具体的讲,包括一个app的创建过程,C#与Java集成在一起开发时候的交互等等,这些问题我们就留在后面慢慢来解决。

参考阅读

http://developer.xamarin.com/guides/android/under_the_hood/architecture/
http://en.wikipedia.org/wiki/Java_Native_Interface
http://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/

C#移动跨平台开发(2)Xamarin移动跨平台解决方案是如何工作的?的更多相关文章

  1. Visual Studio跨平台开发实战(1) - Hello Xamarin!

    原文 Visual Studio跨平台开发实战(1) - Hello Xamarin! 前言 应用程式发展的脚步, 从来没有停过. 从早期的Windows 应用程式, 到网路时代的web 应用程式, ...

  2. Visual Studio跨平台开发(1):Hello Xamarin!

    前言 应用程序发展的脚步, 从来没有停过. 从早期的Windows 应用程序, 到网络时代的web 应用程序, 再到近几年相当盛行的行动装置应用程序(Mobile Application), 身为C# ...

  3. C#跨平台手机应用开发工具Xamarin尝试 与Eclipse简单对比

    Xamarin 支持使用C#开发基于Android.IOS.WindowsPhone应用开发,最大特点C#+跨平台,详细说明问度娘. 安装 研究 想体验研究的点击查看页面 Xamarin For Vi ...

  4. Visual Studio跨平台开发Xamarin

    台湾微软的一系列Visual Studio跨平台开发Xamarin的资料,上面还有视频.具体参看 http://www.microsoft.com/taiwan/newsletter/library/ ...

  5. 【Xamarin开发 Android 系列 2】VS2015跨平台开发的几种方式

    原文:[Xamarin开发 Android 系列 2]VS2015跨平台开发的几种方式 在微软Build大会上,微软宣布在VS2015中支持三种方式进行跨平台的开发. 1. Xamarin 2. Co ...

  6. Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发

    原文 Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发 前言 大部份的Andr​​oid 都具有实体或虚拟的Back键. 因此在处理多页面应用程式时 ...

  7. Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍

    原文 Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍 前言 不同于iOS,Xamarin 在Visual Studio中针对Android,可以直接设 ...

  8. Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发

    原文 Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发 前言 在前一篇教学中, 我们学会如何使用Visual Studio 搭配Xcode 进行iOS基本控 ...

  9. Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍

    原文 Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍 前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iO ...

随机推荐

  1. Ubuntu下使用nvm

    写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...

  2. JS 判断数据类型的三种方法

    说到数据类型,我们先理一下JavaScript中常见的几种数据类型: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Functi ...

  3. vue.js学习笔记

    有了孩子之后,元旦就哪也去不了了(孩子太小),刚好利用一些时间,来公司充充电补补课,学习学习新技术,在这里做一个整理和总结.(选择的东西,既然热爱就把他做好吧!). 下来进入咱们的学习环节: 一.从H ...

  4. c++ pair 使用

    1. 包含头文件: #include <utility> 2. pair 的操作: pair<T1,T2> p; pair<T1,T2> p(v1,v2); pai ...

  5. Angular2 Hello World 之 RC6

    angular2还没有发布正式版,确实有点不靠谱,变化太频繁,之前写的demo直接将js升级到最新版之后发现就不能用了……所以现在在写一篇demo——基于RC6.参考:http://web3.code ...

  6. Mysql - 数据库操作

    之前介绍了数据库的增删改查, 发现忘记了数据库的一些基本操作, 比如建库, 建表, 改表等等. 那这里就来小结一下数据库sql形式的基本操作. 一.库操作 1. 建库 在建库之前, 可能需要看一下, ...

  7. DB2重启数据库实例

    DB2重启数据库实例时,有时停止实例会失败,此时需要先确认没有应用链接数据库,然后再关闭数据库实例,并重新启动. 1.查看是否有活动的链接 命令:db2 list applications for d ...

  8. python安装BeautifulSoup注意事项

    好久没有写爬虫了,最近用Python的BeautifulSoup4.Scrapy分别对以前写的spider进行优化,发现python3.5后这些库变化了很多,遇到了许多问题,在这里做一下总结. 切换环 ...

  9. 08讲browse命令的使用技巧

    .浏览所有parts ,使用技巧 .浏览所有 nets,使用技巧 在上图中选择nets .浏览所有 offpage connector,使用技巧 如上 .浏览所有 DRC makers,使用技巧 5. ...

  10. 【repost】JS中的异常处理方法分享

    我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...