How do their APIs compare?
How do their APIs compare?
About jakewharton/butterknife · 2 messages · last activity 9/8/2026
Here's a comparison of the two libraries' APIs, drawn from what's in the repository data.
jakewharton/butterknife — Annotation-driven binding API
Butter Knife's public surface is almost entirely annotations processed at compile time, not a runtime API you call step-by-step. The pattern is:
- Field binding:
@BindView(R.id.foo)on a field, resolved via generated code rather than reflection at runtime (only oneClass.forNamelookup remains historically, per [CHANGELOG.md:L270-L274]). - Method binding for listeners: annotations like
@OnClick,@OnPageChangemap directly onto Android callback interfaces. For example,@OnPageChangeexposes an innerCallbackenum (PAGE_SELECTED,PAGE_SCROLLED,PAGE_SCROLL_STATE_CHANGED) where each constant is tied via@ListenerMethodto a specific interface method name/parameter signature [butterknife-annotations/src/main/java/butterknife/OnPageChange.java:L47-L74]. This is a declarative mapping — you pick aCallbackvalue and Butter Knife's annotation processor generates the actual listener implementation. - Resource binding:
@BindString,@BindBool,@BindColor,@BindDimen,@BindDrawable,@BindInt,@BindArray,@BindBitmap,@BindFont— these bind Android resources directly to fields, nogetResources()calls needed by the user (see version history in [CHANGELOG.md:L281-L295], [CHANGELOG.md:L246-L256]). - Lifecycle API: a single entry point,
ButterKnife.bind(this), returns anUnbinder(introduced in 8.0.0) so you can null out references later — this replaced the oldinject/unbindpair from 7.0.0 [CHANGELOG.md:L246-L285]. - Grouping: multiple views can be grouped into a
List/array and manipulated viaAction,Setter, or AndroidPropertythroughButterKnife.apply(later moved toViewCollections) [CHANGELOG.md:L351-L360], [CHANGELOG.md:L71-L82]. - Codegen internals: under the hood,
BindingSetin the compiler builds the generated unbind/bind methods, handling null-checks, listener removal, and field naming — e.g.asHumanDescriptionbuilds human-readable error messages listing bound elements [butterknife-compiler/src/main/java/butterknife/compiler/BindingSet.java:L565-L584], andbestGuessmaps primitive/type strings toTypeNamefor codegen [butterknife-compiler/src/main/java/butterknife/compiler/BindingSet.java:L585-L601].
So Butter Knife's "API" is best understood as annotations + one bind call + generated unbind call, with almost no imperative control flow exposed to the caller.
lingochamp/filedownloader — Imperative, service-oriented download API
FileDownloader's API is a much more traditional method-call-driven, stateful engine API centered on the FileDownloader singleton and task builders:
- Engine control methods: things like
stopForeground(boolean)[library/src/main/java/com/liulishuo/filedownloader/FileDownloader.java:L606-L608] andsetMaxNetworkThreadCount(int)[FileDownloader.java:L671-L685], which directly mutate engine-wide state and can fail with warnings if tasks are active. - Deprecated completion-marking API:
setTaskCompleted(String url, String path, long totalBytes)and its bulk overloadsetTaskCompleted(List<FileDownloadTaskAtom>)let callers tell the engine a file was already downloaded outside the library — both are now no-ops that just log a warning, since the DB-based completion tracking was removed in 0.3.3+ [FileDownloader.java:L606-L645], [FileDownloader.java:L646-L669]. - Async binding lifecycle: methods like
insureServiceBind(),insureServiceBindAsync(), andbindService(Runnable)manage the download service's startup before dependent calls execute [CHANGELOG-ZH.md:L474-L484]. - **Pluggable components
Want to ask your own question?
Open chat for jakewharton/butterknifePublic Q&A. Generated by RepoPilot from the actual source of jakewharton/butterknife. AI answers can be incomplete or stale — verify before relying on them.