huanghaibin-dev/CalendarView · error
e.printStackTrace()
Error message
e.printStackTrace()
What it means
CalendarView.init() reflectively instantiates the custom WeekBar class configured via app:calendar_week_bar_view. The constructor lookup (Context argument) or newInstance fails, and the library swallows the exception with printStackTrace, leaving mWeekBar null, which then crashes on frameContent.addView(mWeekBar, 2) with a NullPointerException.
Solutions
- Ensure the custom WeekBar class is public, top-level or static, and has an explicit public constructor taking Context: public MyWeekBar(Context context).
- Check logcat for the swallowed stack trace (ClassNotFoundException / NoSuchMethodException) to identify the exact failure.
- Add a ProGuard keep rule: -keep class com.example.MyWeekBar { public <init>(android.content.Context); }.
- Verify app:calendar_week_bar_view in XML matches the fully-qualified class name exactly.
- As a last resort, temporarily fall back to the default WeekBar (remove the XML attribute) to confirm the custom class is the problem.
Example fix
// before
public class CalendarActivity extends AppCompatActivity {
class MyWeekBar extends WeekBar { public MyWeekBar(Context c){super(c);} }
}
// after
public class MyWeekBar extends WeekBar {
public MyWeekBar(Context context) { super(context); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before setting XML attribute, verify at startup:
Class<?> c = Class.forName("com.example.MyWeekBar");
if (!WeekBar.class.isAssignableFrom(c)) throw new IllegalStateException("Must extend WeekBar");
c.getConstructor(Context.class); // throws if constructor missing
Type guard
static boolean isValidWeekBar(Class<?> cls) {
return WeekBar.class.isAssignableFrom(cls)
&& java.lang.reflect.Modifier.isPublic(cls.getModifiers())
&& !cls.isMemberClass();
} Try / catch
try {
calendarView.setWeekBar(MyWeekBar.class);
} catch (Throwable t) {
Log.e("Calendar", "Custom WeekBar failed, using default", t);
// continue with library default
} Prevention
- Always declare custom calendar views as public top-level (or static) classes.
- Always provide a public constructor that only takes Context.
- Add ProGuard keep rules for every custom calendar view class.
- Test custom view configuration in a minified release build, not just debug.
- Watch logcat at startup for printStackTrace output from CalendarView.
When it happens
Trigger: A custom WeekBar subclass is declared in XML (app:calendar_week_bar_view="com.example.MyWeekBar") but the class is not public, lacks a public MyWeekBar(Context) constructor, is an inner (non-static) class, or was ProGuard/R8-obfuscated or removed at build time.
Common situations: Developers subclass WeekBar inside an Activity as a non-static inner class; enabling minifyEnabled true without a keep rule for the custom view; typo in the fully-qualified class name; the custom class lives in a module not included as a dependency.
Related errors
AI-assisted analysis of huanghaibin-dev/CalendarView@f5479ea3ba (2026-09-11).
Data as JSON: /api/errors/dd59d4c4464fafc3.
Report an issue: GitHub.
Appendix: source
Thrown at calendarview/src/main/java/com/haibin/calendarview/CalendarView.java:108
init(context);
}
/**
* 初始化
*
* @param context context
*/
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.cv_layout_calendar_view, this, true);
FrameLayout frameContent = findViewById(R.id.frameContent);
this.mWeekPager = findViewById(R.id.vp_week);
this.mWeekPager.setup(mDelegate);
try {
Constructor constructor = mDelegate.getWeekBarClass().getConstructor(Context.class);
mWeekBar = (WeekBar) constructor.newInstance(getContext());
} catch (Exception e) {
e.printStackTrace();
}
frameContent.addView(mWeekBar, 2);
mWeekBar.setup(mDelegate);
mWeekBar.onWeekStartChange(mDelegate.getWeekStart());
this.mWeekLine = findViewById(R.id.line);
this.mWeekLine.setBackgroundColor(mDelegate.getWeekLineBackground());
LayoutParams lineParams = (LayoutParams) this.mWeekLine.getLayoutParams();
lineParams.setMargins(mDelegate.getWeekLineMargin(),
mDelegate.getWeekBarHeight(),
mDelegate.getWeekLineMargin(),
0);
this.mWeekLine.setLayoutParams(lineParams);
this.mMonthPager = findViewById(R.id.vp_month);
this.mMonthPager.mWeekPager = mWeekPager;
this.mMonthPager.mWeekBar = mWeekBar;View on GitHub (pinned to f5479ea3ba)