【Xamarin挖牆腳系列:Xamarin.Android的API設計準則】

傑克.陳發表於2016-03-07
原文:【Xamarin挖牆腳系列:Xamarin.Android的API設計準則】

前言

樓主也是看著Xamarin的官方文件來的。基本也是照貓畫虎。英語勉強湊合。翻譯的不對的地方,大家多多指教。(這些東西估計弄不完整,呵呵所以別報太高的期望,樓主也很忙) 

原文地址:http://developer.xamarin.com/guides/android/advanced_topics/api_design/

API Design

 

PDF for offline use:

Let us know how you feel about this.

Overview

In addition to the core Base Class Libraries that are part of Mono, Xamarin.Android ships with bindings for various Android APIs to allow developers to create native Android applications with Mono.

At the core of Xamarin.Android there is an interop engine that bridges the C# world with the Java world and provides developers with access to the Java APIs from C# or other .NET languages.

除了一些基本的核心的BCL類庫是Mono的組成部分,Xamarin.Android 這個類庫為各個版本的Android APIs做了完整的繫結,這就允許使用Mono的開發人員開發原生的安卓程式。Xamarin.Android的設計核心是為C#等其他.net語言的開發者提供了通向Java世界的橋樑。

Design Principles

(略了,一些無非痛癢的東西,就直接忽略了,就挑重要的說)

 

Assemblies

Xamarin.Android includes a number of assemblies that constitute the MonoMobile Profile. The Assemblies page has more information.

The bindings to the Android platform are contained in the Mono.Android.dll assembly. This assembly contains the entire binding for consuming Android APIs and communicating with the Android runtime VM.

Xamarin.Android 專案包含了許多支撐Mono開發移動應用的元件程式集。其中,Mono.Android.dll提供了對Android平臺的對應的SDK的一對一的影射繫結。這個程式集中,包含了所有的安卓API,實現可以與Android虛擬機器通訊互動。

 

Binding Design

Collections

The Android APIs utilize the java.util collections extensively to provide lists, sets, and maps. We expose these elements using the System.Collections.Generic interfaces in our binding. The fundamental mappings are:

Java Type System Type Helper Class
java.util.Set<E> ICollection<T> Android.Runtime.JavaSet<T>
java.util.List<E> IList<T> Android.Runtime.JavaList<T>
java.util.Map<K,V> IDictionary<TKey,TValue> Android.Runtime.JavaDictionary<K,V>
java.util.Collection<E> ICollection<T> Android.Runtime.JavaCollection<T>

 

 

We have provided helper classes to facilitate faster copyless marshaling of these types. When possible, we recommend using these provided collections instead of the framework provided implementation, like List<T> or Dictionary<TKey, TValue>. The Android.Runtime implementations utilize a native Java collection internally and therefore do not require copying to and from a native collection when passing to an Android API member.

You can pass any interface implementation to an Android method accepting that interface, e.g. pass a List<int> to theArrayAdapter<int>(Context, int, IList<int>) constructor. However, for all implementations except for the Android.Runtime implementations, this involves copying the list from the Mono VM into the Android runtime VM. If the list is later changed within the Android runtime (e.g. by invoking the ArrayAdapter<T>.Add(T) method), those changes will not be visible in managed code. If a JavaList<int> were used, those changes would be visible.

Rephrased, collections interface implementations that are not one of the above listed Helper Classes only marshal [In]:

 1 // This fails:
 2 var badSource  = new List<int> { 1, 2, 3 };
 3 var badAdapter = new ArrayAdapter<int>(context, textViewResourceId, badSource);
 4 badAdapter.Add (4);
 5 if (badSource.Count != 4) // true
 6     throw new InvalidOperationException ("this is thrown");
 7 
 8 // this works:
 9 var goodSource  = new JavaList<int> { 1, 2, 3 };
10 var goodAdapter = new ArrayAdapter<int> (context, textViewResourceId, goodSource);
11 goodAdapter.Add (4);
12 if (goodSource.Count != 4) // false
13     throw new InvalidOperationException ("should not be reached.");

 

 我覺得這段很重要,但是篇幅有點長,不一一翻譯了。意思是:雖然Mono專案提供了對Java對應的API的影射繫結,但是,在實際應用中,我們推薦使用 Android.Runtime 名稱空間下對應的集合類,這些輔助類可以讓我們既能實現對集合的複雜操作

又可以跟android執行時互動。也就是在ADT 安卓執行時操作這些事例的時候,在託管程式碼 Mono 中也可以被影響。如果使用System.Collection下的集合,那麼這些集合其實在ADT中是被進行了複製操作。轉化成了對應的ADT下的型別

注意:這樣就不能進行兩邊的雙向通知。比如上面的那個例子。UI元件接受的引數接受任意的集合型別,但是,如果使用的是List IList,那麼當UI元件中的元素髮送變化的時候,並不能通知託管程式碼中的集合。相反,使用JavaList是可以的。所以:針對集合的操作,推薦使用Android.Runtime 下面的集合工具類。

 

Properties

 

Java methods are transformed into properties, when appropriate:

 

  • The Java method pair T getFoo() and void setFoo(T) are transformed into the Foo property. Example: Activity.Intent .
  • The Java method getFoo() is transformed into the read-only Foo property. Example: Context.PackageName .
  • Set-only properties are not generated.
  • Properties are not generated if the property type would be an array.

就是把類中的 【屬性】成員  set foo() get foo() 設計為 C#中的 {get;set}

只讀成員 設計為C#的  read only

只讀成員是非泛型的

除非是泛型的陣列型別,否則屬性不會是泛型成員屬性。

 

Events and Listeners

UI中的元件的事件,對應到C#中的就是 委託!!!delegate 或者 Action 或者 Handler 委託型別的設計 。

var button = new Android.Widget.Button (context) {
    Text = string.Format ("{0} clicks!", this.count),
};
button.Click += (sender, e) => {
    button.Text = string.Format ("{0} clicks!", ++this.count);
};

Runnables

Java utilizes the java.lang.Runnable interface to provide a delegation mechanism. The java.lang.Thread class is a notable consumer of this interface. Android has employed the interface in the API as well. Activity.runOnUiThread() and View.post() are notable examples.

The Runnable interface contains a single void method, run(). It therefore lends itself to binding in C# as a System.Actiondelegate. We have provided overloads in the binding which accept an Action parameter for all API members which consume aRunnable in the native API, e.g. Activity.RunOnUiThread() and View.Post().

We left the IRunnable overloads in place instead of replacing them since several types implement the interface and can therefore be passed as runnables directly.

java.lang.Runnable 介面提供了委託實現機制。額,不清楚啥意思。應該是C#中的委託型別 ,是Java中的Runnable介面型別的的一種繫結。比如C#中的Action委託。

 

Inner Classes

(略)

Interfaces

介面型別

Java interfaces can contain three sets of members, two of which cause problems from C#:

  1. Methods.
  2. Types.
  3. Fields.

這個比較操蛋的設計,Java語言中的介面型別可以有 方法 ,型別 Type,欄位。但是Type 和欄位是不允許出現在C#中的!所以,這種介面型別被轉化成了兩種候選方案

1 一個同名的介面型別,僅僅包含方法

2 一個靜態的型別,包含所有的欄位

(下面就略了)

 

 

Resources

所以的圖片 佈局 檔案  String.xml檔案,都放置到專案的此目錄下。每次新增 或者重新命名檔案,都會在 Resource.Designer.cs的類中,生成或修改對應的資源標識。

Constants and Enumerations

 

常亮和列舉

這些就更不用說了,完全一對一的從Android的API中,影射繫結到Mono.Android中了。

 

 

 

 

 

 

 

 

 

 

 


相關文章