如何進行 APK 的閃退除錯
這篇文章將會記錄,當您的開發的應用程式已經安裝到使用者的手機上了,此時,發生了閃退現象,但您沒有任何支援閃退問題紀錄的工具來幫助您顯示問題;這個時候,您可以透過此篇文章,進行低階 Log 除錯。
這篇文章將會使用 Xamarin.Forms 的 Todo 範例程式,您可以從此下載這個專案。
設定 Todo 專案會發生異常閃退
- 請開啟 Todo 專案
- 滑鼠右擊 TodoPCL
>
Targets>
Todo.Android專案
,選擇設定為起始專案
- 專案組態可以選擇
Debug
- 請將手機插到電腦 USB 上,並且進入到 USB 偵錯模式。
- 在方案總管中,展開
TodoPCL
>Targets
>Todo.Android
專案,使用滑鼠雙擊Properties
節點 - 切換到
Android Options
標籤頁次,接著請在標題Linking
節點上,選擇Sdk Assemblies Only
,接著,執行這個專案此時,您會發現這個專案可以正常在您的手機上執行 - 在方案總管中,展開
TodoPCL
>Targets
>Todo.Android
專案,使用滑鼠雙擊Properties
節點 - 切換到
Android Options
標籤頁次,接著請在標題Linking
節點上,選擇Sdk and User Assemblies
,接著,執行這個專案此時,您會發現到您的專案無法在手機上執行。現在,您的手機上已經有一個 Xamarin.Forms 製作的應用程式,並且一旦執行這個應用程式,該程式就會閃退。
準備進行閃退應用程式偵錯
- 請將有安裝閃退應用程式的手機,接上電腦,而該手機必須進入開發者模式,並允許 USB 除錯。
- 使用 Visual Studio 開啟這個 Todo 專案。
- 點選功能表
工具
>Android
>Android Device Logging...
開啟Android Device Logging
視窗 - 若
Android Device Logging
視窗內,看不到任何訊息- 請點選左上方的手機螢幕圖示
- 在開啟的
Select Device
對話窗內,選擇您的手機,並且點選OK
按鈕
- 在
Android Device Logging
視窗下,請確認長的如下圖- 確認下圖標示 (1) 的地方,為正在進行蒐集 Log 狀態
- 請切換到
Text View
模式 - 當要進行應用程式閃退問題蒐集前,可以點選
Clear
按鈕,隨時清空多餘的訊息。
進行應用程式閃退問題蒐集
- 請點選
Clear
按鈕 - 請在手機中執行有問題的程式
- 當程式閃退之後,請點選 停止紀錄訊息按鈕,此時,
Android Device Logging
視窗如下所示 Android Device Logging
視窗內,按下 Ctrl + A 接著按下 Ctrl + C ,把所有的訊息複製下到。您可以將這些內容貼到如記事本
程式內來做分析- 請搜尋這個關鍵字
FATAL EXCEPTION: mai
找到此次異常閃退的問題紀錄- 在
java.lang.RuntimeException:
之下的紀錄,為 Android 這裡 Java 發出的持行時期例外異常 - 在
Caused by: android.runtime.JavaProxyThrowable:
之後的紀錄,說明了 Xamarin.Android 這裡產生的例外異常紀錄。 - 底下訊息可以看出
Position 6:31. No method listItemSelected found on type Todo.TodoItemListX
應用程式在這個時候,找不到Todo.TodoItemListX
這個類別的建構式。而真正的原因是,Xamarin.Android 的 Linker 在進行組件連結的時候,因為使用靜態分析方法,導致Todo.TodoItemListX
這個類別被 Linker 移除掉了。Force finishing activity Todo.Android/md5321ee62e7307662a691059f7f382b8e6.MainActivity
這個訊息則是記錄下,這個應用程式此時要結束執行了,也就是要閃退了。
07-28 19:33:12.845 E/AndroidRuntime(13163): FATAL EXCEPTION: main
07-28 19:33:12.845 E/AndroidRuntime(13163): Process: Todo.Android, PID: 13163
07-28 19:33:12.845 E/AndroidRuntime(13163): java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
07-28 19:33:12.845 E/AndroidRuntime(13163): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
07-28 19:33:12.845 E/AndroidRuntime(13163): Caused by: java.lang.reflect.InvocationTargetException
07-28 19:33:12.845 E/AndroidRuntime(13163): at java.lang.reflect.Method.invoke(Native Method)
07-28 19:33:12.845 E/AndroidRuntime(13163): at java.lang.reflect.Method.invoke(Method.java:372)
07-28 19:33:12.845 E/AndroidRuntime(13163): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
07-28 19:33:12.845 E/AndroidRuntime(13163): ... 1 more
07-28 19:33:12.845 E/AndroidRuntime(13163): Caused by: android.runtime.JavaProxyThrowable: Xamarin.Forms.Xaml.XamlParseException: Position 6:31. No method listItemSelected found on type Todo.TodoItemListX
07-28 19:33:12.845 E/AndroidRuntime(13163): at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue (System.Object xamlelement, XmlName propertyName, System.Object value, System.Object rootElement, INode node, Xamarin.Forms.Xaml.HydratationContext context, IXmlLineInfo lineInfo) <0xf092e618 + 0x0035b> in <filename unknown>:0
07-28 19:33:12.845 E/AndroidRuntime(13163): at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit (Xamarin.Forms.Xaml.ValueNode node, INode parentNode) <0xf092df98 + 0x0034b> in <filename unknown>:0
07-28 19:33:12.845 E/AndroidRuntime(13163): at Xamarin.Forms.Xaml.ValueNode.Accept (IXamlNodeVisitor visitor, INode parentNode) <0xf0942878 + 0x00023> in <filename unknown>:0
07-28 19:33:12.845 E/AndroidRuntime(13163): at Xamarin.Forms.Xaml.ElementNode.Accept (IXamlNodeVisitor visitor, INode parentNode) <0xf09428f8 + 0x000f7> in <filename unknown>:0
- 解決方式請參考下圖,這是因為:
- 使用標題
Skip linking assemblies:
下的欄位,輸入QuickTodo
,表示,這個組件不需要進行 Link 連結分析處理。 Todo.TodoItemListX
這個類別位於QuickTodo
這個組件內。- 請反覆這些步驟,把需要排除的組件逐一加回來即可。