我维护了一个导致崩溃的库,让我感到困惑。
该库为用户提供了扩展View
的自定义FrameLayout
。此自定义View
在其构造函数中访问单例(也由库定义):
CustomView(Context context, AttributeSet attributeSet, int defStyleAttr) {
super(context, attributeSet, defStyleAttr);
// Other initialization.
mySingleton = MySingleton.getSharedInstance();
}
// Two-parameter and one-parameter constructors delegate to the three-parameter constructor above.
如果先前未调用配置方法MySingleton::getSharedInstance
,则方法MySingleton::initSharedInstance
会抛出异常:
private static void initSharedInstance(Application application) {
synchronized (MySingleton.class) {
if (sharedInstance == null) {
sharedInstance = new MySingleton(application);
}
}
}
public static MySingleton getSharedInstance() {
synchronized (MySingleton.class) {
if (sharedInstance == null) {
throw new IllegalStateException("You must call initSharedInstance before calling getSharedInstance.");
}
}
return sharedInstance;
}
我指示图书馆用户使用MySingleton::initSharedInstance
方法拨打Application::onCreate
,并向报告此次崩溃的用户确认他们正在这样做。
这是一个示例堆栈跟踪:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.activity.ManageCamerasActivity}: android.view.InflateException: Binary XML file line #11: Binary XML file line #1: Error inflating class com.github.stkent.amplify.prompt.DefaultLayoutPromptView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: android.view.InflateException: Binary XML file line #11: Binary XML file line #1: Error inflating class com.github.stkent.amplify.prompt.DefaultLayoutPromptView
at android.view.LayoutInflater.inflate(LayoutInflater.java:551)
at android.view.LayoutInflater.inflate(LayoutInflater.java:429)
at android.view.LayoutInflater.inflate(LayoutInflater.java:380)
at android.support.v7.app.m.b(SourceFile:288)
at android.support.v7.app.e.setContentView(SourceFile:140)
at com.example.activity.ManageCamerasActivity.onCreate(SourceFile:232)
at android.app.Activity.performCreate(Activity.java:6904)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3266)
... 9 more
Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class com.github.stkent.amplify.prompt.DefaultLayoutPromptView
at android.view.LayoutInflater.createView(LayoutInflater.java:657)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:966)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:843)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:810)
at android.view.LayoutInflater.inflate(LayoutInflater.java:527)
... 17 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.view.LayoutInflater.createView(LayoutInflater.java:631)
... 22 more
Caused by: java.lang.IllegalStateException: You must call initSharedInstance before calling getSharedInstance.
at com.github.stkent.amplify.b.a.b(SourceFile:101)
at com.github.stkent.amplify.prompt.a.<init>(SourceFile:113)
at com.github.stkent.amplify.prompt.DefaultLayoutPromptView.<init>(SourceFile:52)
at com.github.stkent.amplify.prompt.DefaultLayoutPromptView.<init>(SourceFile:44)
... 24 more
显然,MySingleton::getSharedInstance
之前正在调用MySingleton::initSharedInstance
,即CustomView
之前正在调用Application::onCreate
构造函数,但我不知道具体情况如何。我认为在执行任何Application
/ Activity
/ Fragment
代码之前,View
实例始终是完全创建的。
这里发生了什么?
N.B。:如果链接到更具体的实施细节会有用,请对此作出评论。
答案 0 :(得分:-1)
在getSharedInstance(Application a)中执行:if(instance == null){ initSharedInstance(a); }