XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2016/07/29

Xamarin.Forms 的 Linker 選擇

Xamarin.Forms 的 Linker 選擇

不論是 Xamarin.Andriod 或者是 Xamarin.iOS,在其專案屬性內都有一個 Linker 的選項,這是因為 Xamarin 提供了當編譯完成 C# 的程式語言並且產生相對應的組件檔案,您可以指定 Xamarin 是否要針對產生出來的組件進行 靜態分析 決定出哪個組件(Assembley)實際上是有被使用、哪個型別(Type)實際上是有被使用並且哪個成員(Member)實際上有被使用。 Linker 的分析過程類似 CRL(Common Runtime Library) 的垃圾回收 (Garbage Collector) 處理方式,會持續地尋找組件、類型、成員,看看這些元素是否有被參考到;最後,將沒有參考的元素,將會被 Linker 忽略掉,也就是不會產生在 APK 檔案裡面。
這裡的相關範例將會使用 Xamarin.Android 模式下來操作,當然,同樣的操作,在 Xamarin.iOS 操作方式也是一樣。

將範例專案進行不同的 Linker 設定

  1. 使用 Visual Studio 2015 打開範例專案 DoggyMobileBE.sln
  2. 使用滑鼠雙擊 DoggyMobileBE.Droid 專案 > Properties 節點
  3. 當出現 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的設定

比較範例專案的不同 Linker 模式下,產生的 APK 檔案

在這裡設定這個 Xamarin.Android 專案使用的 Debug 組態模式,分別進行 NoneSdk Assemblies Only,Sdk and User Assemblies 這三種 Linker 模式的建置與產生 APK,得到結果如下:
NoneSdk Assemblies OnlySdk and User Assemblies
APK檔案大小60MB21.5MB17.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
UnhandledException
要解決這樣的問題有底下方法:
  1. 採用 None 的模式來進行 Linker 處理,不過,這樣產生的 APK 檔案室會相當大的。
  2. 使用 Sdk Assemblies Only 的模式來進行 Linker 處理,也就是說,Linker 僅會將 來自於 Xamarin.Android 的組件進行 Linker 靜態分析,並且移除掉沒有用到的組件、型別或者成員,而其他的組件就不會進行 Linker 處理。
  3. 若您一定想要使用 Sdk and User Assemblies Linker 模式,您需要逐步將意外被 Linker 移除的組件內容,把他強制加回來。

明確指名不要 Linker 的組件

這個方法比較適合用於您沒有原始碼組件,例如,使用 NuGet 加入的套件。
  1. 請在設定 Linker 的同一個標籤頁面
  2. 在 Skip linking assemblies 標題下方,將核心 PCL 的組件加入到這個欄位內,告知 Linker 要排除這個組件,不要做任何連結分析的處理行為。
  3. 接著,再度執行程式,詳細執行您應用程式的每個地方,看看有那些地方還是會產生例外異常的閃退行為,找出其所屬的組件,回到步驟 2
  4. 持續處理,直到沒有發生任何例外異常的閃退行為。

使用 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 引數內
    iOSXMLNoLink
  • 底下為一個 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>

沒有留言:

張貼留言