Xamarin.Forms 的 Linker 選擇
這裡的相關範例將會使用 Xamarin.Android 模式下來操作,當然,同樣的操作,在 Xamarin.iOS 操作方式也是一樣。
將範例專案進行不同的 Linker 設定
- 使用 Visual Studio 2015 打開範例專案
DoggyMobileBE.sln - 使用滑鼠雙擊
DoggyMobileBE.Droid專案 >Properties節點 - 當出現 Xamarin.Android 的專案屬性頁面,請點選
Android Options>Linker您可以從標籤Linking:下方的下拉選單,選擇:- None這個選項將會關閉
Linker的功能,也就是說,當在這個模式下的時候,所產生的 APK 檔案體積是最大的。若您選擇其他模式,會造成您的應用程式異常閃退,建議可以先切換到這個模式下,確認在這個模式下產生的程式不會有任何異常閃退,接著再進行了解是要把哪個組件或者型別排除在Linker模式之外。 - Sdk Assemblies Only在這個模式下,僅僅會針對來自於
Xamarin.Android的組件進行Linker靜態分析,這些組件您可以參考網址https://developer.xamarin.com/guides/cross-platform/advanced/available-assemblies/。而不在這清單內的組將,將不會進行Linker處理。 - Sdk and User Assemblies這個模式會將產生最小檔案體積的 APK 檔案,所有的組件都會進行
Linker分析,當然,檔案變小,就代表了程式的載入時間變短、加快執行效率。 

 
比較範例專案的不同 Linker 模式下,產生的 APK 檔案
在這裡設定這個 Xamarin.Android 專案使用的 
Debug 組態模式,分別進行 None, Sdk Assemblies Only,Sdk and User Assemblies 這三種 Linker 模式的建置與產生 APK,得到結果如下:| None | Sdk Assemblies Only | Sdk and User Assemblies | |
|---|---|---|---|
| APK檔案大小 | 60MB | 21.5MB | 17.8MB | 
您可以從上面的表格中,看到採用 
Sdk and User Assemblies Linker 模式下所產生出來的 APK,其檔案體積最小,可是,很不幸的,當您使用這個模式產生的 APK 檔案,安裝到使用者手機上之後,一旦執行,就會閃退。
要如何解決此一問題,後面將會有建議一個步驟,不過,先來看看這三種模式下產生的 APK 檔案內容,底下的內容,為使用 zip 解壓縮軟體,把 APK 檔案解壓縮之後,使用 DIR 指令查看 
assemblies 目錄下所得到的結果。None
2016/07/19  上午 12:17            22,016 DoggyMobileBE.dll
2016/07/29  下午 10:06               931 DoggyMobileBE.dll.config
2016/07/29  下午 10:05             3,781 DoggyMobileBE.dll.mdb
2016/07/29  下午 10:06            90,112 DoggyMobileBE.Droid.dll
2016/07/29  下午 10:06             9,078 DoggyMobileBE.Droid.dll.mdb
2016/01/18  下午 03:36            13,824 FormsViewGroup.dll
2016/06/20  下午 03:37           114,688 Java.Interop.dll
2016/06/20  下午 02:03            44,745 Java.Interop.dll.mdb
2016/06/20  下午 03:37            30,720 Microsoft.CSharp.dll
2016/06/20  下午 03:36            10,126 Microsoft.CSharp.dll.mdb
2016/07/07  上午 11:50           327,704 Microsoft.WindowsAzure.Mobile.dll
2016/07/07  上午 11:50            93,208 Microsoft.WindowsAzure.Mobile.Ext.dll
2016/06/20  下午 03:40        22,217,216 Mono.Android.dll
2016/06/20  下午 03:40         7,604,642 Mono.Android.dll.mdb
2016/06/20  下午 03:37         1,350,144 Mono.CSharp.dll
2016/06/20  下午 03:36           438,175 Mono.CSharp.dll.mdb
2016/06/20  下午 03:37         3,646,976 mscorlib.dll
2016/06/20  下午 03:36         1,496,781 mscorlib.dll.mdb
2014/08/03  下午 08:33           444,928 Newtonsoft.Json.dll
2016/06/20  下午 03:37             6,144 System.Collections.Concurrent.dll
2016/06/20  下午 03:37             6,144 System.Collections.dll
2016/06/20  下午 03:37           270,848 System.ComponentModel.Composition.dll
2016/06/20  下午 03:36           137,422 System.ComponentModel.Composition.dll.mdb
2016/06/20  下午 03:37             4,608 System.ComponentModel.dll
2016/06/20  下午 03:37           869,376 System.Core.dll
2016/06/20  下午 03:36           359,097 System.Core.dll.mdb
2016/06/20  下午 03:37             4,608 System.Diagnostics.Debug.dll
2016/06/20  下午 03:37             4,608 System.Diagnostics.Tools.dll
2016/06/20  下午 03:37         1,806,336 System.dll
2016/06/20  下午 03:36           768,066 System.dll.mdb
2016/06/20  下午 03:37             6,656 System.Dynamic.Runtime.dll
2016/06/20  下午 03:37             5,120 System.Globalization.dll
2016/06/20  下午 03:37             5,120 System.IO.dll
2016/06/20  下午 03:37             5,632 System.Linq.dll
2016/06/20  下午 03:37             7,168 System.Linq.Expressions.dll
2016/06/20  下午 03:37             4,608 System.Linq.Queryable.dll
2016/06/20  下午 03:37           122,368 System.Net.Http.dll
2016/06/20  下午 03:36            48,067 System.Net.Http.dll.mdb
2015/02/19  下午 08:10            22,232 System.Net.Http.Extensions.dll
2015/02/19  下午 08:10            21,720 System.Net.Http.Primitives.dll
2016/06/20  下午 03:37             5,632 System.Net.Primitives.dll
2016/06/20  下午 03:37             5,632 System.ObjectModel.dll
2016/06/20  下午 03:37             5,632 System.Reflection.dll
2016/06/20  下午 03:37             4,608 System.Reflection.Extensions.dll
2016/06/20  下午 03:37             4,608 System.Resources.ResourceManager.dll
2016/06/20  下午 03:37            13,824 System.Runtime.dll
2016/06/20  下午 03:37             5,120 System.Runtime.Extensions.dll
2016/06/20  下午 03:37             6,144 System.Runtime.InteropServices.dll
2016/06/20  下午 03:37           889,856 System.Runtime.Serialization.dll
2016/06/20  下午 03:36           322,073 System.Runtime.Serialization.dll.mdb
2016/06/20  下午 03:37             5,120 System.Runtime.Serialization.Primitives.dll
2016/06/20  下午 03:37           227,840 System.ServiceModel.Internals.dll
2016/06/20  下午 03:36            89,254 System.ServiceModel.Internals.dll.mdb
2016/06/20  下午 03:37             5,120 System.Text.Encoding.dll
2016/06/20  下午 03:37             4,608 System.Text.Encoding.Extensions.dll
2016/06/20  下午 03:37             4,608 System.Text.RegularExpressions.dll
2016/06/20  下午 03:37             5,632 System.Threading.dll
2016/06/20  下午 03:37             6,656 System.Threading.Tasks.dll
2016/06/20  下午 03:37         2,432,512 System.Xml.dll
2016/06/20  下午 03:36           953,244 System.Xml.dll.mdb
2016/06/20  下午 03:37           133,632 System.Xml.Linq.dll
2016/06/20  下午 03:36            50,083 System.Xml.Linq.dll.mdb
2016/06/20  下午 03:37             6,656 System.Xml.ReaderWriter.dll
2016/06/20  下午 03:37             6,144 System.Xml.XDocument.dll
2048/11/30  上午 05:06           286,208 Xamarin.Android.Support.Design.dll
1980/01/01  上午 12:00         1,872,384 Xamarin.Android.Support.v4.dll
2047/01/23  下午 07:30           953,856 Xamarin.Android.Support.v7.AppCompat.dll
2047/10/19  上午 12:34            33,792 Xamarin.Android.Support.v7.CardView.dll
2047/07/28  下午 03:19           198,144 Xamarin.Android.Support.v7.MediaRouter.dll
2016/01/18  下午 03:36           426,496 Xamarin.Forms.Core.dll
2016/01/18  下午 03:36           230,400 Xamarin.Forms.Platform.Android.dll
2016/01/18  下午 03:36            71,168 Xamarin.Forms.Platform.dll
2016/01/18  下午 03:36            61,440 Xamarin.Forms.Xaml.dll
Sdk Assemblies Only
2016/07/29  下午 10:08            22,016 DoggyMobileBE.dll
2016/07/29  下午 10:08               931 DoggyMobileBE.dll.config
2016/07/29  下午 10:08             3,713 DoggyMobileBE.dll.mdb
2016/07/29  下午 10:08            90,112 DoggyMobileBE.Droid.dll
2016/07/29  下午 10:08             9,078 DoggyMobileBE.Droid.dll.mdb
2016/07/29  下午 10:08            11,776 FormsViewGroup.dll
2016/07/29  下午 10:08            92,672 Java.Interop.dll
2016/07/29  下午 10:08            34,533 Java.Interop.dll.mdb
2016/06/20  下午 03:37            30,720 Microsoft.CSharp.dll
2016/07/29  下午 10:08           327,168 Microsoft.WindowsAzure.Mobile.dll
2016/07/29  下午 10:08            84,992 Microsoft.WindowsAzure.Mobile.Ext.dll
2016/07/29  下午 10:08         1,532,928 Mono.Android.dll
2016/06/20  下午 03:37         1,350,144 Mono.CSharp.dll
2016/07/29  下午 10:08         2,186,752 mscorlib.dll
2016/07/29  下午 10:08           446,464 Newtonsoft.Json.dll
2016/06/20  下午 03:37           869,376 System.Core.dll
2016/07/29  下午 10:08           665,600 System.dll
2016/07/29  下午 10:08            83,456 System.Net.Http.dll
2016/07/29  下午 10:08             5,632 System.Net.Http.Extensions.dll
2016/07/29  下午 10:08             5,120 System.Net.Http.Primitives.dll
2016/07/29  下午 10:08           442,368 System.Runtime.Serialization.dll
2016/06/20  下午 03:37           227,840 System.ServiceModel.Internals.dll
2016/07/29  下午 10:07            89,254 System.ServiceModel.Internals.dll.mdb
2016/07/29  下午 10:08         1,052,672 System.Xml.dll
2016/07/29  下午 10:08            46,080 System.Xml.Linq.dll
2048/11/30  上午 05:06           286,208 Xamarin.Android.Support.Design.dll
1980/01/01  上午 12:00         1,872,384 Xamarin.Android.Support.v4.dll
2047/01/23  下午 07:30           953,856 Xamarin.Android.Support.v7.AppCompat.dll
2047/10/19  上午 12:34            33,792 Xamarin.Android.Support.v7.CardView.dll
2047/07/28  下午 03:19           198,144 Xamarin.Android.Support.v7.MediaRouter.dll
2016/07/29  下午 10:08           465,408 Xamarin.Forms.Core.dll
2016/07/29  下午 10:08           235,520 Xamarin.Forms.Platform.Android.dll
2016/07/29  下午 10:08            78,848 Xamarin.Forms.Platform.dll
2016/07/29  下午 10:08            63,488 Xamarin.Forms.Xaml.dll
Sdk and User Assemblies
2016/07/29  下午 10:10            14,336 DoggyMobileBE.dll
2016/07/29  下午 10:10               931 DoggyMobileBE.dll.config
2016/07/29  下午 10:10             2,362 DoggyMobileBE.dll.mdb
2016/07/29  下午 10:10            90,112 DoggyMobileBE.Droid.dll
2016/07/29  下午 10:10             9,078 DoggyMobileBE.Droid.dll.mdb
2016/07/29  下午 10:10            11,776 FormsViewGroup.dll
2016/07/29  下午 10:10            92,160 Java.Interop.dll
2016/07/29  下午 10:10            34,308 Java.Interop.dll.mdb
2016/06/20  下午 03:37            30,720 Microsoft.CSharp.dll
2016/07/29  下午 10:10           120,320 Microsoft.WindowsAzure.Mobile.dll
2016/07/29  下午 10:10            84,992 Microsoft.WindowsAzure.Mobile.Ext.dll
2016/07/29  下午 10:10         1,338,368 Mono.Android.dll
2016/06/20  下午 03:37         1,350,144 Mono.CSharp.dll
2016/07/29  下午 10:10         2,177,024 mscorlib.dll
2016/07/29  下午 10:10           310,784 Newtonsoft.Json.dll
2016/06/20  下午 03:37           869,376 System.Core.dll
2016/07/29  下午 10:10           640,000 System.dll
2016/07/29  下午 10:10            83,456 System.Net.Http.dll
2016/07/29  下午 10:10             5,120 System.Net.Http.Extensions.dll
2016/07/29  下午 10:10           442,368 System.Runtime.Serialization.dll
2016/07/29  下午 10:10            58,368 System.ServiceModel.Internals.dll
2016/07/29  下午 10:10            14,321 System.ServiceModel.Internals.dll.mdb
2016/07/29  下午 10:10         1,052,672 System.Xml.dll
2016/07/29  下午 10:10            46,080 System.Xml.Linq.dll
2016/07/29  下午 10:10            40,960 Xamarin.Android.Support.Design.dll
2016/07/29  下午 10:10           369,664 Xamarin.Android.Support.v4.dll
2016/07/29  下午 10:10           402,944 Xamarin.Android.Support.v7.AppCompat.dll
2016/07/29  下午 10:10            25,088 Xamarin.Android.Support.v7.CardView.dll
2016/07/29  下午 10:10             5,632 Xamarin.Android.Support.v7.MediaRouter.dll
2016/07/29  下午 10:10           465,408 Xamarin.Forms.Core.dll
2016/07/29  下午 10:10           235,520 Xamarin.Forms.Platform.Android.dll
2016/07/29  下午 10:10            77,824 Xamarin.Forms.Platform.dll
2016/07/29  下午 10:10            63,488 Xamarin.Forms.Xaml.dll
解決因為 Linker 造成意外移除的問題
當在 
Sdk and User Assemblies Linker 模式下執行,會產生一個例外異常:
Xamarin.Forms.Xaml.XamlParseException: Position 29:19. No method OnAdd found on type DoggyMobileBE.TodoList

要解決這樣的問題有底下方法:
- 採用
None的模式來進行Linker處理,不過,這樣產生的 APK 檔案室會相當大的。 - 使用
Sdk Assemblies Only的模式來進行Linker處理,也就是說,Linker 僅會將 來自於 Xamarin.Android 的組件進行 Linker 靜態分析,並且移除掉沒有用到的組件、型別或者成員,而其他的組件就不會進行 Linker 處理。 - 若您一定想要使用
Sdk and User AssembliesLinker 模式,您需要逐步將意外被 Linker 移除的組件內容,把他強制加回來。 
明確指名不要 Linker 的組件
這個方法比較適合用於您沒有原始碼組件,例如,使用 NuGet 加入的套件。
- 請在設定 Linker 的同一個標籤頁面
 - 在
Skip linking assemblies標題下方,將核心 PCL 的組件加入到這個欄位內,告知 Linker 要排除這個組件,不要做任何連結分析的處理行為。 - 接著,再度執行程式,詳細執行您應用程式的每個地方,看看有那些地方還是會產生例外異常的閃退行為,找出其所屬的組件,回到步驟 2
 - 持續處理,直到沒有發生任何例外異常的閃退行為。
 
使用 Android.Runtime.Preserve 從 Linker 中排除
- 底下為將 Example 這個類別的建構式從 Linker 中排除
 
public class Example
{
    [Android.Runtime.Preserve]
    public Example ()
    {
    }
}
- 底下為要保留整個類別,不要在 Linker
 
[Android.Runtime.Preserve (AllMembers = true)]
class Example
{
    // Compiler provides default constructor...
}
使用自訂 Linker 的設定檔案
您可以產生一個 XML 內容的檔案,加入到原生專案內,不過,對於不同原生專案,需要做不同的設定
- Xamarin.Android
建置動作需要指定LinkDescription - Xamarin.iOS請把這個文字
--xml=FILE在 mtouch 引數內
 - 底下為一個 XML 範例
 
<linker>
        <assembly fullname="mscorlib">
                <type fullname="System.Environment">
                        <field name="mono_corlib_version" />
                        <method name="get_StackTrace" />
                </type>
        </assembly>
        <assembly fullname="My.Own.Assembly">
                <type fullname="Foo" preserve="fields">
                        <method name=".ctor" />
                </type>
                <type fullname="Bar">
                        <method signature="System.Void .ctor(System.String)" />
                        <field signature="System.String _blah" />
                </type>
                <namespace fullname="My.Own.Namespace" />
                <type fullname="My.Other*" />
        </assembly>
</linker>
靜態分析決定出哪個組件(Assembley)實際上是有被使用、哪個型別(Type)實際上是有被使用並且哪個成員(Member)實際上有被使用。Linker的分析過程類似 CRL(Common Runtime Library) 的垃圾回收 (Garbage Collector) 處理方式,會持續地尋找組件、類型、成員,看看這些元素是否有被參考到;最後,將沒有參考的元素,將會被Linker忽略掉,也就是不會產生在 APK 檔案裡面。