Skip to content

Stasis is a general purpose library to persist state using annotation processing and code generation.

License

Notifications You must be signed in to change notification settings

tierable/Stasis

Repository files navigation

Stasis

Build Status

Download Stasis Lib Download Stasis Lib

Download Stasis Lib Android Download Stasis Lib Android

Download Stasis Compiler Download Stasis Compiler

Stasis is a general purpose library to persist state using annotation processing and code generation.

The (Android) problem

Android user interface classes (Activitys, Fragments, etc) provide a (limited) mechanism to save important bits of the UI state (the onSavedInstanceState(Bundle) and onRestoreInstanceState(Bundle) mechanism). However, in practice this is not comprehensive enough to fully restore the UI. There's flags that aren't commonly known by developers (like freezesText for TextViews), data that can't normally be accessed, or other things that can't be stored properly in a Bundle (like adapters, etc).

Stasis provides an Android specialisation with sensible defaults for UI state preservation.

Usage

Stasis uses a similar approach to Jake Wharton's ButterKnife library. In a class you'd like to preserve, just annotate the relevant fields with the @Preserve annotation and the annotation processor generates a PreservationStrategy for your class.

Downloading dependencies

In your modules build.gradle dependencies, add:

compile "com.tierable.stasis:stasis-lib:$stasisVersion"
// For Android projects
compile "com.tierable.stasis:stasis-lib-android:$stasisVersion"

To enable annotation processing:

For Android:

annotationProcessor "com.tierable.stasis:stasis-compiler:$stasisVersion"

For Java

apt "com.tierable.stasis:stasis-compiler:$stasisVersion"

For Kotlin?

kapt "com.tierable.stasis:stasis-compiler:$stasisVersion"

Providing a mapping class

Provide a single interface (for now?) in your module and mark it with the @PreservationMapping annotation. You can define a fallback strategy if you don't want to define a mapping for every type of preserved class. The default fallback strategy is to not save anything.

The mapping interface can extend other interfaces. Methods in the interface:

  • Can be named whatever you desire (as long as it makes sense). The getStrategy name has been used in examples as an appropriate name though
  • Must return a PreservationStrategy
  • Can have more than one parameter if you need the same PreservationStrategy for multiple types
// Uses the marker annotation
@PreservationMapping(MyFallbackPreservationStrategy.class)
public interface DemoMapping 
	extends AnotherMapping, YetAnotherMapping {
	// Multiple mappings for a PreservationStrategy
	PreservationStrategyButton getStrategy(Button button, ButtonChildClass buttonChildClass);

	// Single mapping for a PreservationStrategy
	PreservationStrategyTextField getStrategy(TextField textField);

	// etc
}

Creating custom preservation strategies

Just create a class implementing the PreservationStrategy interface or extending a pre-existing PreservationStrategy. The only limitation is that you can only use the default (no argument) constructor for generated code.

Preserving state

Stasis generates a PreservationStrategy implementation for every class with atleast one member annotated with @Preserve. The generated class names will be in the format PreservationStrategy[YourClassNameHere] and will be outputted to the same package. Preserved fields must be either public or package private so they are accessible by the generated code.

public class DemoClass {

	@Preserve
	Button buttonWithADefaultPreservationStrategy;

	@Preserve(value = MyCustomButtonPreservationStrategy.class)
	Button buttonWithACustomPreservationStrategy;

	@Preserve(enabled = false)
	Button buttonWithPreservationDisabled;

	Button buttonNotPreserved;

	// Generated by Stasis
	private PreservationStrategyDemoClass preservationStrategy;
	
	
	public void initialise() {
		preservationStrategy = new PreservationStrategyDemoClass();
	}
	
	public void saveState() {
		// 'Freeze'/'save' this classes state
		preservationStrategy.freeze(this);
		
		// TODO: save the preservationStrategy somewhere
	}
	
	public void restoreState() {
		// TODO: Restore the preservationStrategy from somewhere
		
		// 'UnFreeze'/'restore' this classes state
		preservationStrategy.unFreeze(this);
	}
	
	// etc
}

About

Stasis is a general purpose library to persist state using annotation processing and code generation.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published