News Patch requests and updates

Writing patches

API: App runtime

The app runtime is code the engine adds to the patched app, the first time a patch uses it. Your extensions compile against it and call it while the app runs. Your bundle never ships it, and any number of bundles share one copy in an app.

Everything here is in app.reseam.runtime, and runs on the phone, unlike the rest of the API, which runs while patching.

Exports

Export

Marks an extension class, method, constructor, or field that patches refer to. The build generates a binding for every class that has exports, so patches can call it. See Export what patches call.

Member Description
@Export Exports the member under its own name.
@Export(name = "…") Exports it under another binding name, which two overloads need.

Settings in extensions

The build generates an object for each of your settings groups, in the same package and with the same name, for your extensions to compile against. Each property is a value of the matching class below.

import app.example.settings.AppSettings

if (AppSettings.hideAds.value) hide(view)
AppSettings.feedStyle.value = "cards"
AppSettings.feedStyle.reset()

Before the app runtime has started, in the app's Application.onCreate, every value reads as its default, and writing fails.

SettingValue

The base of every setting value.

Member Description
bundle: String Your bundle's name.
key: String The setting's key.
default: T Its default.
value: T Its current value. Set it to change the setting.
reset() Sets it back to the default.

ToggleValue

A toggle's value, as Boolean. A toggle covered by another one that is on reads as true.

TextValue

A text setting's value, as String.

FolderValue

A folder setting's value, as String, the folder's address. It also has:

pick(activity: Activity, onPicked: Runnable) opens the system folder picker over activity. When the user picks a folder, it becomes the value, with permission to read and write it, and onPicked runs on the main thread. A cancelled pick runs nothing.

ChoiceValue

A choice setting's value, as String. A stored value that the setting no longer lists reads as the default.

Strings in extensions

The build generates an object for each of your string tables, with the same name as the patch side's table. A string without arguments is a String property. A string with arguments is a function named after it, taking the xliff:g arguments in order. A plural takes its count first.

Toast.makeText(context, ExampleStrings.downloadSaved(folder), Toast.LENGTH_SHORT).show()
val label = ExampleStrings.itemsHidden(count)

Each string shows in the app's current language, including Android's per-app language setting, and falls back to the default text when a translation lacks it. Reading a string before the app runtime has started fails.

StringTable

What the generated objects read through. You rarely use it directly.

Member Description
StringTable(directory: String) The table stored in the app at directory.
get(name: String): String A string without arguments, written table["name"].
format(name: String, vararg args: Any?): String A string with arguments.
plural(name: String, count: Int, vararg args: Any?): String A plural, in the form the current language uses for count.

Reaching the runtime

Reseam

The app runtime's entry point.

Member Description
isStarted: Boolean Whether the runtime has started. The settings host starts it first in the app's Application.onCreate.
bundle(name: String): ReseamBundle A bundle's settings and components. Fails before the runtime has started, or when the app has no settings for that bundle.
init(context: Context) Starts the runtime. The settings host calls it for you, and later calls do nothing.
isEnabled(bundle: String, key: String, defaultValue: Boolean): Boolean A toggle's value by key. Generated setting values call this.
getString(bundle: String, key: String, defaultValue: String): String A text setting's value by key.
getChoice(bundle: String, key: String, defaultValue: String): String A choice setting's value by key.
openSettings(bundle: String) Opens a bundle's settings over the current screen.
startActivity(context: Context, intent: Intent) Opens settings for an intent that opensSettings set up, and starts any other intent as usual.

ReseamBundle

One bundle in the app, from Reseam.bundle(name).

Member Description
name: String The bundle's name.
settings: Settings Its stored settings.
ui(context: Context): Ui Builds branded components in the bundle's brand and the settings screen's current light or dark theme.
openSettings() Opens its settings over the current screen. It works from any thread.

Settings

A bundle's stored settings, by key. The generated setting values are usually simpler.

Member Description
getBoolean(key: String, defaultValue: Boolean): Boolean A toggle. A covered toggle reads as on while a toggle that covers it is on.
getString(key: String, defaultValue: String): String A text or folder setting.
getChoice(key: String): String A choice setting. A stored value it no longer lists reads as its default.
setBoolean(key: String, value: Boolean), setString(key: String, value: String) Changes a setting.
addOnChangeListener(listener: OnChangeListener) Calls listener.onChanged(key) on the main thread after every change, until removed. A null key means every value was cleared.
removeOnChangeListener(listener: OnChangeListener) Stops calling the listener.

Branded components

Views your extensions build in your bundle's brand, for their own screens and dialogs:

val ui = Reseam.bundle("my-patches").ui(activity)
ui.dialog()
    .title(ExampleStrings.downloadFinished)
    .message(ExampleStrings.downloadSavedToDownloads)
    .dismissAction(ExampleStrings.close)
    .action(ExampleStrings.open) { open(file) }
    .show()

They follow Material 3, in the settings screen's current light or dark theme: the one the user picked, and until they pick, the system's, or before Android 10 the app's own.

Ui

Member Description
context: Context, theme: Theme What it builds with.
colors: Colors The current theme's colors.
type: Typography The brand's type roles.
px(dp: Float): Int Converts dp to pixels.
text(value: CharSequence?, style: TypeStyle, color: Int): TextView Text in a type role.
icon(image: VectorImage, sizeDp: Int, tint: Int): ImageView An icon, ignored by screen readers.
iconButton(image: VectorImage, tint: Int, description: CharSequence?, onClick: View.OnClickListener?): ImageView An icon button. Screen readers read description.
button(label: CharSequence?, onClick: View.OnClickListener?): TextView A text button.
tonalButton(label: CharSequence?, image: VectorImage, onClick: View.OnClickListener?): View A filled button with an icon.
listItem(title: CharSequence?): ListItem A list row.
itemGroup(): ItemGroup A group of list rows with shared rounded corners.
sectionLabel(label: CharSequence?): TextView A heading above a group.
switchView(): SwitchView A switch.
searchBar(hint: CharSequence?): SearchBar A search field.
textField(label: CharSequence?): TextField An outlined text field.
topBar(title: CharSequence?, back: Runnable): TopBar A screen's top bar with a back button.
dialog(): BrandDialog.Builder A dialog.
shape(color: Int, radiusDp: Float), shape(color: Int, topDp: Float, bottomDp: Float): GradientDrawable A rounded background.
ripple(content: Drawable?, topDp: Float, bottomDp: Float, stateColor: Int): RippleDrawable A touch ripple over a background.

ListItem

A list row, a View. Each setter returns the row, so calls chain.

Member Description
icon(image: VectorImage?) The leading icon.
title(value: CharSequence?) The title.
supporting(value: CharSequence?) The line under the title.
trailing(view: View?) A view at the end, such as a switch.
chevron() A trailing arrow, for a row that opens something.
onClick(listener: View.OnClickListener?) Makes the row clickable.

ItemGroup

A LinearLayout of rows. add(item: ListItem): ItemGroup appends one, and rounds the group's first and last corners.

SwitchView

A Material 3 switch, a View that is Checkable. setOnCheckedChangeListener(listener) calls onCheckedChanged(view, checked) when the user flips it.

A search field, a LinearLayout. onQueryChange(listener) calls onQueryChanged(query) as the user types.

TextField

An outlined text field, a LinearLayout.

Member Description
field: EditText The editable text view inside.
text: String The current text.
text(value: CharSequence?): TextField Sets the text.
multiline(lines: Int): TextField Lets the text wrap, showing this many lines.
action(icon: VectorImage, description: CharSequence?, onClick: View.OnClickListener?): TextField An icon button at the end of the field.
showAction(visible: Boolean) Shows or hides that button.

TopBar

A screen's top bar, with a back button that runs back.

Member Description
action(icon: VectorImage, description: CharSequence?, onClick: View.OnClickListener?): TopBar An icon button at the end of the bar. Screen readers read description.

BrandDialog.Builder

What ui.dialog() returns. Each setter returns the builder.

Member Description
icon(icon: VectorImage?) An icon above the title.
title(title: CharSequence?) The title.
message(message: CharSequence?) The body text.
view(view: View?) A view of your own as the body.
choices(choices: Array<out CharSequence?>?, selected: Int, onChoose: OnChooseListener?) A list of options, with selected marked. onChoose gets the picked index.
action(label: CharSequence?, onClick: Runnable?) A button that closes the dialog, then runs onClick. Add the confirming action last.
dismissAction(label: CharSequence?) A button that only closes the dialog.
onDismiss(onDismiss: Runnable?) Runs when the dialog closes, however it closes.
show(): Dialog Builds and shows it.

Theme

The brand in the current light or dark theme.

Member Description
brand: Brand, dark: Boolean The brand, and whether the theme is dark.
logo: VectorImage? The brand's logo for this theme.
typeface(weight: Int): Typeface The brand's font at a weight.
style(view: TextView, style: TypeStyle) Sets a text view in a type role.

Colors

The current theme's colors, as Android color ints, one per Material 3 role: primary, onPrimary, primaryContainer, onPrimaryContainer, secondaryContainer, onSecondaryContainer, surface, surfaceContainerLow, surfaceContainer, surfaceContainerHigh, surfaceContainerHighest, onSurface, onSurfaceVariant, outline, outlineVariant, error, onError, errorContainer, onErrorContainer, and scrim.

Typography and TypeStyle

The brand's type roles: headlineSmall, titleLarge, titleMedium, bodyLarge, bodyMedium, labelLarge, and labelMedium. Each TypeStyle has size, lineHeight, and tracking in sp, and a weight. Apply one with ui.text or theme.style.

VectorImage

A vector image from your brand or a setting's icon, drawn at any size. Draw one with ui.icon.

Icons

Line icons the runtime's own screens use, which your components can use too: ARROW_LEFT, CHEVRON_RIGHT, SEARCH, CLOSE, CHECK, RESET, SUN, MOON, UPLOAD, and DOWNLOAD.

Used by the runtime itself

These are public so the runtime's parts can reach each other. Extensions don't need them: Tokens and Motion (spacing, sizes, and animations of the runtime's screens), DocumentRequest (the screen that runs the system file pickers), and ReseamReactPackage (the React Native module Hermes gates read settings through, which addReactPackage adds).

Edit this page