代码改变世界

Mono for Andriod学习与实践(1)— 初体验

2015-01-29 14:44  Dorisoy  阅读(265)  评论(0编辑  收藏  举报

 对于Andriod的开发者来说,相信Java语言是第一选择,可是对于.Net开发者来说,要想利用C#在Andriod平台上开发,Mono提供了相应的开发平台来实现,Mono for Andriod就是专门为.Net开发者设计的Andriod手机端开发平台。

Mono for Andriod官方文档:http://docs.xamarin.com/android

 

      Mono for Andriod完全绑定于Andriod Java API,因此,在您安装Mono for Andriod时,必须先安装JDK以及Andriod SDK,这样才能够顺利进行开发。

      Mono for Andriod可与Java、C/C++进行交互操作,也就是说Mono for Andriod可以直接调用Java,C,C++的类库。

      Mono for Android的应用程序是以.Net BCL为基础,BCL即Base Class Library,它提供了XML, Database, Serialization, IO, String, and Networking等等支持。它的集成开发环境是MonoDevelop或者Visual Studio都可以。

      移动跨平台支持,例如Mono for Andriod和MonoTouch(C#版IOS开发平台)可以共用一套后台的公共代码,当然相信未来也受用于Windows Phone 7。

      Mono for Andriod是构建于Mono之上,Mono是一个基于.NET ECMA标准的.Net Framework的开源版本,可运行于Linux, UNIX, FreeBSD, Mac OSX等等。

      当您编译一个Mono for Andriod应用程序的时候,主要包括三个步骤:

1. 源产生,作为预编译阶段,aresgen.exe运行资源目录,例如Resource.Designer.cs,UI File,Images等资源文件

2. 编译成托管的.Net或者Mono应用程序集

3. Andriod安装包的创建:生成apk文件,通过mandroid.exe工具进行打包

 

Mono for Andriod安装

目前支持在Windows以及Mac下的安装,这里以Windows为例:

下载地址:http://xamarin.com/trial

您也可以参考它的安装文档:http://docs.xamarin.com/android/getting_started/installation/Installation_for_Windows

image

这里我选择的是企业版的安装文件setup.exe

image

运行之,首先它会监测你的计算机是否已经安装了相关的准备,包括JDK(据说目前不支持Java 7,没有试过,因为计算机已经安装了JDK 6)、Andriod SDK、MonoDevelop 3.0.2、Mono Andriod Tool等等,建议这里讲Andriod SDK中的所有版本全部安装,便于调试不同版本的应用程序。

全部安装好了之后,可以在MonoAndriod的Framework的程序集路径C:\Program Files\Reference Assemblies\Microsoft\Framework\MonoAndroid中看到:

 image

 

另外在目录中,还可以发现mono.android.jar,说明mono也支持Jar包的调用。

在我的本地已经安装了Andriod所有版本的mono.andriod包

image

现在,不管在您的Monodevelop还是VS中,都可以打开一个AVD Manager的窗口,在该窗口中你可以设置本地的模拟器以及启动它:

image

通过Start按钮,就可以打开相应的Andriod模拟器。

 

      Mono for Andriod的试用版本可以在任意的模拟器上供你开发学习,如果你需要发布、部署到真实设备中,或者发布到App Store中,就需要购买相应版权,企业版一般授权费用$999,专业版一般授权费用$399,详见:https://store.xamarin.com/

 

      在开发Mono for Andriod应用程序之前,首先必须要先了解一下Mono for Andriod的构成:

Mono for Andriod的BCL是以Silverlight和Client .NET3.5程序集为基础,它包括了丰富的程序集:

1. Base Class Library

      主要包括mscrolib.dll,System.dll,System.Core.dll,System.Data.dll,System.Json.dll,System.Runtime.Serialization.dll,

System.ServiceModel.dll,System.ServiceModel.Web.dll,System.Transactions.dll,System.Web.Services.dll,

System.Xml.dll,System.Xml.Linq.dll等等

2. Mono for Android Framework

      主要包括Mono.Android.dll,Mono.Andriod.dll作为Andriod开发中最核心的部分,它直接和Andriod API进行绑定

3. Mono Libraries

      主要包括Mono.xml.dll,Mono.Security.dll,Mono.Data.Tds.dll,Mono.Data.Sqlite.dll,

Mono.CompilerServices.SymbolWriter.dll等等

另外在MonoAndriod的Framework中还可以看到一个OpenTK.dll,它是OpenGL/OpenAL的封装,通过它可以设计3D的模型,在Andriod游戏开发中相当有用。

 

Activity与Activity生命周期

      Activities作为Andriod应用程序的基础组件,不管是在mono还是非mono下,这个概念是相同的。

      在Andriod操作系统中使用优先级栈来管理activities在设备中的运行,而Activity 的生命周期是交给系统统一管理,在android中,Activity拥有四种基本状态:

1. Active/Runing:一个新Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。 
2. Paused:当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。 
3. Stopped:当Activity被另外一个Activity覆盖、失去焦点并不可见时处于Stopped状态。 
4. Killed:Activity被系统杀死回收或者没有被启动时处于Killed状态。 
当一个Activity 实例被创建、销毁或者启动另外一个Activity时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作,下图说明了 Activity 在不同状态间转换的时机和条件(参考文章:http://www.ibm.com/developerworks/cn/opensource/os-cn-android-actvt/):

image

Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:

image002

如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。

Activity生命周期调用顺序:

image

参考MonoAndriod的一段代码:

复制代码
[Activity (Label = "Hello M4A", MainLauncher = true)] 
public class Activity1 : Activity 
{
protected override void OnCreate (Bundle bundle) 

base.OnCreate (bundle); 

//Use UI created in Main.axml 
SetContentView(Resource.Layout.Main); 

var aButton = FindViewById<Button> (Resource.Id.aButton); 
var aLabel = FindViewById<TextView> (Resource.Id.helloLabel); 

aButton.Click += (sender, e) => {aLabel.Text = "Hello from the button";}; 

}
复制代码

所有的活动页面基本是基于Activity来实现(当然andriod 3.0版本之上还可以通过Fragment的UI组件来实现),通过OnCreate完成Activity的首次构建。

具体Activity生命周期还可以参考官方文档:http://docs.xamarin.com/android/tutorials/Activity_Lifecycle

     

       Activity之间的数据通信是通过使用Intent类来实现,在官方的Demo中大量使用Intent类,不同的Intent类型实现了不同的功能,这个在后面的文章中我会具体在作出介绍。

 

最后,通过一个示例的介绍来看看怎样创建一个Mono for Andriod应用程序,(以VS为例):

当你安装好Mono for Andriod的一切之后,我们可以在VS的新建项目中看到:

image

新建一个Andriod项目,在解决方案中我们看到产生一系列的目录以及文件:

image

 

Asserts包含应用程序需要在其中任何类型的文件,这里包含的文件通过Asserts类就可以进行访问,其中需要设定相关文件的生成操作为AndriodAsset:

image

您可以通过代码来访问文件的内容,例如:

InputStream input = Assets.Open ("AboutAssets.txt");

Resources包含应用程序资源,如字符串和图像,以及声明性XML(Andriod XML)的用户界面(这里统一放在Layout中)定义。这些资源是通过生成Resources类进行访问,同样需要设定文件的生成操作:

  image

Values中的String.xml作为本地的资源字符串文件进行配置,例如:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="helloButtonText">Say Hello</string> 
    <string name="helloLabelText">Hello Mono for Android</string> 
</resources> 

通过代码访问:

var aLabel = new TextView (this);
aLabel.SetText(Resource.String.helloLabelText);
var aButton = new Button (this);
aButton.SetText(Resource.String.helloButtonText);

 

Activity1.cs就是新建的一个继承于Activity类的实现,通过这个类可以编写页面的相关逻辑。

 

Mono for Andriod最终将Code以及Resources文件等等编译执行打包成为.apk文件,如下图所示:

image

编写代码:

复制代码
[Activity (Label = "Hello M4A", MainLauncher = true)] 
public class Activity1 : Activity 

    protected override void OnCreate (Bundle bundle) 
    { 
        base.OnCreate (bundle);
        SetContentView(Resource.Layout.Main); 
        
        var aButton = FindViewById<Button> (Resource.Id.aButton); 
        var aLabel = FindViewById<TextView> (Resource.Id.helloLabel); 
        
        aButton.Click += (sender, e) => {aLabel.Text = "Hi, Leepy!";};                 
    } 
复制代码

以及Main.axml:

复制代码
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"> 
<TextView 
        android:id="@+id/helloLabel" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/helloLabelText" /> 
<Button 
        android:id="@+id/aButton" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/helloButtonText" /> 
</LinearLayout>
复制代码

具体实现的说明我会在下篇具体介绍

现在要运行应用程序,先开启一个Andriod 2.2版本的模拟器:

image

调试执行程序

image

选择刚刚启动的模拟器,(注:应用程序在首次加载时,首先会将相关的mono Assembles 和 mono for andriod framework包安装到模拟器中,打包的apk文件也会安装到模拟器中,这个过程要等待几分钟)

image

点击“Say Hello”按钮,在TextView控件中显示“Li,Leepy”。