我正在使用Xamarin Android开发Android应用程序。
我正试图通过
捕捉全球异常AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) =>
{
//WRITE TO FILE
};
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
/*
* When a background thread crashes this is the code that will be executed. You can
* recover from this.
*/
};
我仍然经常在各种设备上收到“不幸的应用已经停止了错误”。错误没有被发现。
我怀疑是内存泄漏,但我不确定。我无法访问经常出现此错误的设备的logcat文件。我的智慧结束了。任何人都可以对此有所了解吗?
另一方面,如果引发全局异常并将其捕获,则UnhandledExceptionRaiser会在两者之间中断并且不会写入文件(我猜这是因为Android会清理进程吗?)
答案 0 :(得分:3)
在分析Google崩溃报告后,我发现了实际错误。
11-12 22:36:31.410: E/AndroidRuntime(4835): FATAL EXCEPTION: main
11-12 22:36:31.410: E/AndroidRuntime(4835): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.apptimator.pro.mayusha/com.apptimator.mayusha.HomeActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@42ab6ad8: Unmarshalling unknown type code 7209057 at offset 1064
......
11-12 22:36:31.410: E/AndroidRuntime(4835): Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@42ab6ad8: Unmarshalling unknown type code 7209057 at offset 1064
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.os.Parcel.readValue(Parcel.java:2038)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.os.Parcel.readMapInternal(Parcel.java:2255)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.os.Bundle.unparcel(Bundle.java:223)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.os.Bundle.getSparseParcelableArray(Bundle.java:1237)
11-12 22:36:31.410: E/AndroidRuntime(4835): at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1969)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.app.Activity.onRestoreInstanceState(Activity.java:977)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.app.Activity.performRestoreInstanceState(Activity.java:949)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1155)
11-12 22:36:31.410: E/AndroidRuntime(4835): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2271)
此错误可能由this ("Proguard Causing Runtime exception")或在此Xamarin Android案例中导致,由于嵌套的保存状态实现而无法恢复已保存的实例状态。
我在Home Activity中使用了SlidingMenuSharp(SlidingMenuSharp link)库,它实现了IParcelable并使用了嵌套的SavedState类。可以找到相同的错误here
尽管如此,我设法解决了这个问题,现在一切正常。要修复错误,请按照提到的SavedState,OnRestoreInstanceState和OnSaveInstanceState的Bundle实现进行操作
public class SavedState : BaseSavedState
{
public int Item { get; private set; }
public SavedState(IParcelable superState)
: base(superState)
{
}
public SavedState(Parcel parcel)
: base(parcel)
{
Item = parcel.ReadInt();
}
public override void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
{
base.WriteToParcel(dest, flags);
dest.WriteInt(Item);
}
[ExportField("CREATOR")]
static SavedStateCreator InitializeCreator()
{
return new SavedStateCreator();
}
class SavedStateCreator : Java.Lang.Object, IParcelableCreator
{
public Java.Lang.Object CreateFromParcel(Parcel source)
{
return new SavedState(source);
}
public Java.Lang.Object[] NewArray(int size)
{
return new SavedState[size];
}
}
}
protected override void OnRestoreInstanceState(IParcelable state)
{
try
{
Bundle bundle = state as Bundle;
if (bundle != null)
{
IParcelable superState = (IParcelable)bundle.GetParcelable("base");
if (superState != null)
base.OnRestoreInstanceState(superState);
_viewAbove.SetCurrentItem(bundle.GetInt("currentPosition", 0));
}
}
catch
{
base.OnRestoreInstanceState(state);
// Ignore, this needs to support IParcelable...
}
}
protected override IParcelable OnSaveInstanceState()
{
var superState = base.OnSaveInstanceState();
Bundle state = new Bundle();
state.PutParcelable("base", superState);
state.PutInt("currentPosition", _viewAbove.GetCurrentItem());
return state;
}
答案 1 :(得分:0)
您不应使用AppDomain.CurrentDomain.UnhandledException
来拦截未处理的异常,如Xamarin docs中所述:
注意:您不能依赖AppDomain.UnhandledException事件 托管异常永远不会在MonoDroid中处理;他们总是 在捕获中的Android /托管边界截获(例外) 块。
我建议继续使用AndroidEnvironment.UnhandledExceptionRaiser
并尽可能高效地保持操作。
还可以使用TaskScheduler.UnobservedTaskException
捕获在后台线程中发生但未观察到的异常(并且不会导致未处理的异常)。
最后,我订阅了我的应用程序类(继承自Android.App.Application的类)中的所有异常处理事件,因为它是应用程序的第一个入口点,甚至可以有例外在您的主要活动开始之前(或从现在开始订阅的任何地方)
P.S。我也使用TaskScheduler.UnobservedTaskException
只是为了安全起见,但从来没有发现任何例外。