├── .gitignore ├── README.md ├── README_zh.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── savestate │ │ └── prototype │ │ └── github │ │ └── io │ │ └── io │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── prototypez │ │ │ └── savestate │ │ │ └── activity │ │ │ ├── MainActivity.java │ │ │ └── SmartKotlinActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_smart_kotlin.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── savestate │ └── prototype │ └── github │ └── io │ └── io │ └── ExampleUnitTest.java ├── build.gradle ├── core ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── io │ └── github │ └── prototypez │ └── savestate │ └── core │ ├── ParameterizedTypeHelper.java │ └── annotation │ ├── AutoRestore.java │ └── SaveState.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── javaModule ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── github │ │ └── prototypez │ │ └── savestate │ │ └── plain │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── prototypez │ │ │ └── savestate │ │ │ └── plain │ │ │ ├── JavaFragment.java │ │ │ ├── JavaView.java │ │ │ ├── activity │ │ │ ├── JavaActivity.java │ │ │ ├── JavaFragmentActivity.java │ │ │ └── JavaViewActivity.java │ │ │ └── entity │ │ │ └── User.java │ └── res │ │ ├── layout │ │ ├── activity_fragment_java.xml │ │ ├── activity_java.xml │ │ ├── activity_view_java.xml │ │ ├── fragment_java.xml │ │ └── view_java.xml │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── io │ └── github │ └── prototypez │ └── savestate │ └── plain │ └── ExampleUnitTest.java ├── kotlinmodule ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── github │ │ └── prototypez │ │ └── savestate │ │ └── kotlin │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── io │ │ │ └── github │ │ │ └── prototypez │ │ │ └── savestate │ │ │ └── kotlin │ │ │ ├── KotlinFragment.kt │ │ │ ├── KotlinView.kt │ │ │ ├── activity │ │ │ ├── KotlinActivity.kt │ │ │ ├── KotlinFragmentActivity.kt │ │ │ └── KotlinViewActivity.kt │ │ │ └── entity │ │ │ └── Response.kt │ └── res │ │ ├── layout │ │ ├── activity_fragment_kotlin.xml │ │ ├── activity_kotlin.xml │ │ ├── activity_view_kotlin.xml │ │ ├── fragment_kotlin.xml │ │ └── view_kotlin.xml │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── io │ └── github │ └── prototypez │ └── savestate │ └── kotlin │ └── ExampleUnitTest.java ├── logo.png ├── plugin ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── groovy │ └── io │ │ └── github │ │ └── prototypez │ │ └── savestate │ │ ├── ActivitySaveStateTransform.groovy │ │ ├── Constant.groovy │ │ ├── FragmentSaveStateTransform.groovy │ │ ├── SaveState.groovy │ │ ├── SaveStatePlugin.groovy │ │ ├── SaveStateTransform.groovy │ │ ├── ViewSaveStateTransform.groovy │ │ └── util │ │ ├── Compressor.groovy │ │ └── Decompression.groovy │ └── resources │ └── META-INF │ └── gradle-plugins │ └── save.state.properties ├── processor ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── io │ └── github │ └── prototypez │ └── savestate │ └── processor │ ├── BundleStateHelper.java │ ├── CommonSaveStateGenerator.java │ ├── Constant.java │ ├── Generator.java │ ├── SaveStateProcessor.java │ └── ViewSaveStateGenerator.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | .idea/ 12 | repo 13 | build/ 14 | out/ 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SaveState 2 | [ ![Download](https://api.bintray.com/packages/prototypez/maven/save-state/images/download.svg) ](https://bintray.com/prototypez/maven/save-state/_latestVersion) 3 | 4 | 5 | ![](https://raw.githubusercontent.com/PrototypeZ/SaveState/master/logo.png) 6 | 7 | [**中文文档**](https://github.com/PrototypeZ/SaveState/blob/master/README_zh.md) 8 | 9 | Automatically save and restore states of Activities, Fragments and Views. 10 | 11 | No boilerplate code like `onSaveInstanceState` or `onRestoreInstanceState` any more. 12 | 13 | ## Getting started 14 | 15 | Just add the `@AutoRestore` annotation to your fields that need to be saved and restored in Activities, Fragments and Views. 16 | 17 | #### In Activities: 18 | 19 | ```kotlin 20 | class MyActivity : Activity() { 21 | 22 | @AutoRestore 23 | var myInt: Int = 0; 24 | 25 | @AutoRestore 26 | var myRpcCall: IBinder? = null; 27 | 28 | @AutoRestore 29 | var result: String? = null; 30 | 31 | override fun onCreate(savedInstanceState: Bundle?) { 32 | // Your code here 33 | } 34 | } 35 | ``` 36 | 37 | #### In Fragments: 38 | 39 | 40 | ```kotlin 41 | class MyFragment : Fragment() { 42 | 43 | @AutoRestore 44 | var currentLoginUser: User? = null; 45 | 46 | @AutoRestore 47 | var networkResponse: List>? = null; 48 | 49 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 50 | // Your code here 51 | } 52 | } 53 | ``` 54 | 55 | 56 | #### In Views: 57 | 58 | 59 | ```kotlin 60 | class MyView : FrameLayout { 61 | 62 | @AutoRestore 63 | val someText: String? = null; 64 | 65 | @AutoRestore 66 | val size: Size? = null; 67 | 68 | @AutoRestore 69 | val myFloatArray: FloatArray? = null; 70 | 71 | constructor(context: Context) : super(context) { 72 | // your code here 73 | } 74 | 75 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { 76 | // your code here 77 | } 78 | 79 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 80 | // your code here 81 | } 82 | 83 | } 84 | ``` 85 | 86 | Yes, that's all. 87 | 88 | ## Setting up the dependency of SaveState 89 | 90 | Add the plugin classpath to the `build.gradle` file in project root as below: 91 | 92 | ```groovy 93 | buildscript { 94 | 95 | repositories { 96 | google() 97 | jcenter() 98 | } 99 | dependencies { 100 | // your other dependencies 101 | 102 | // dependency for save-state 103 | classpath "io.github.prototypez:save-state:${latest_version}" 104 | } 105 | } 106 | ``` 107 | 108 | Currently the latest version of SaveState is: [ ![Download](https://api.bintray.com/packages/prototypez/maven/save-state/images/download.svg) ](https://bintray.com/prototypez/maven/save-state/_latestVersion) 109 | 110 | Then apply the SaveState plugin in your `build.gradle` file of your **application** module: 111 | 112 | ```groovy 113 | apply plugin: 'com.android.application' 114 | apply plugin: 'save.state' 115 | ``` 116 | 117 | If your module contains `kotlin` code, please make sure `kotlin-kapt` plugin is also included: 118 | ```groovy 119 | apply plugin: 'com.android.application' 120 | apply plugin: 'kotlin-android' 121 | apply plugin: 'kotlin-kapt' 122 | apply plugin: 'save.state' 123 | ``` 124 | 125 | If you have **library** modules and they also need SaveState support, then the only thing you need to do is applying the plugin in their `build.gradle` files just as the **application** module. 126 | 127 | ```groovy 128 | apply plugin: 'com.android.library' 129 | apply plugin: 'save.state' 130 | ``` 131 | 132 | If this **library** module contains `kotlin` code,just follow the same tips in **application** module above: 133 | ```groovy 134 | apply plugin: 'com.android.library' 135 | apply plugin: 'kotlin-android' 136 | apply plugin: 'kotlin-kapt' 137 | apply plugin: 'save.state' 138 | ``` 139 | 140 | 141 | > Note:In pure Java module,SaveState use `annotationProcessor` by default; 142 | In module that contains `kotlin` code, SaveState use `kotlin-kapt` plugin instead. 143 | If you are using SaveState plugin in module that contains `kotlin` code, 144 | please make sure other annotation processor framework are using `kapt` plugin too. 145 | For example, Dagger and DeepLinkDispatch processor should be included as follows: 146 | > ```groovy 147 | > kapt "com.google.dagger:dagger-compiler:${dagger_version}" 148 | > kapt "com.airbnb:deeplinkdispatch-processor:${deeplinkdispatch_version}" 149 | > ``` 150 | 151 | 152 | ## Supported Types 153 | 154 | If the type of a field annotated by the `@AutoRestore` annotation is one of the types below, then there's no configurations any more. SaveState will save and restore your field automatically. 155 | 156 | 157 | Primitive types( including boxed types ) | Classes and interfaces | Array types 158 | -----------------------|----------------|------- 159 | int/Integer | Serializable | byte[] 160 | long/Long | IBinder | short[] 161 | short/Short | Bundle | char[] 162 | float/Float | CharSequence | float[] 163 | double/Double | Parcelable | CharSequence[] 164 | byte/Byte | Size | Parcelable[] 165 | char/Character | SizeF | 166 | boolean/Boolean | String | 167 | 168 | ## Other types 169 | 170 | If the type of a field is not included in what is listed above, but it can be serialized to `JSON` , 171 | then SaveState could still save and restore it automatically by serializing it to `JSON` and deserializing the `JSON` string back to object. 172 | 173 | For example: 174 | 175 | ```kotlin 176 | class User ( 177 | val name: String, 178 | val age: Int 179 | ) 180 | 181 | 182 | class NetworkResponse ( 183 | val resultCode: Int, 184 | val data: T? 185 | ) 186 | ``` 187 | 188 | These types are supported by SaveState according to the rule above: 189 | 190 | ```kotlin 191 | class MyActivity : Activity() { 192 | 193 | @AutoRestore 194 | var user: User? = null 195 | 196 | @AutoRestore 197 | var response: NetworkResponse>? = null 198 | } 199 | ``` 200 | 201 | But we need extra configurations now: 202 | 203 | 1. Make sure your have already included one of the dependencies of **supported `JSON` processing library** . 204 | 2. Add compile options in the `build.gradle` file ( **application** module or **library** module ), 205 | 206 | For pure Java modules: 207 | ```groovy 208 | defaultConfig { 209 | 210 | // your other configs 211 | 212 | // config the JSON processing library 213 | javaCompileOptions { 214 | annotationProcessorOptions { 215 | arguments = [ serializer : "/*Supported JSON processing library*/" ] 216 | } 217 | } 218 | } 219 | ``` 220 | 221 | For modules that contain `kotlin` code: 222 | ```groovy 223 | kapt { 224 | arguments { 225 | arg("serializer", "/*Supported JSON processing library*/") 226 | } 227 | } 228 | ``` 229 | 230 | 231 | Currently the **supported `JSON` processing library** includes: 232 | 233 | + [gson](https://github.com/google/gson) 234 | + [fastjson](https://github.com/alibaba/fastjson) 235 | + [jackson](https://github.com/FasterXML/jackson) 236 | 237 | ## FAQ 238 | 239 | + Q: Does SaveState support Instant Run? 240 | 241 | A: Yes,it's based on Transform API, so no problem. 242 | 243 | + Q: Do I need to add any Proguard rules for release? 244 | 245 | A: No, there's no reflection, so you are safe to use Proguard. 246 | 247 | + Q: What about the performance of SaveState? 248 | 249 | A: It's based on byte code transforming and annotation processor, so the runtime performance is as good as other compiled code written by yourself. 250 | It will only have a little influence on the compile time, but I think it can be ignored. 251 | 252 | + Q: What about the size of SaveState? How much will it increase the APK size? 253 | 254 | A: SaveState do all the jobs at compile time,it doesn't have any runtime dependency, so it won't increase your APK size. 255 | 256 | ## LICENSE 257 | 258 | Copyright (c) 2016-present, SateState Contributors. 259 | 260 | Licensed under the Apache License, Version 2.0 (the "License"); 261 | you may not use this file except in compliance with the License. 262 | You may obtain a copy of the License at 263 | 264 | http://www.apache.org/licenses/LICENSE-2.0 265 | 266 | Unless required by applicable law or agreed to in writing, software 267 | distributed under the License is distributed on an "AS IS" BASIS, 268 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 269 | See the License for the specific language governing permissions and 270 | limitations under the License. -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # SaveState 2 | [ ![Download](https://api.bintray.com/packages/prototypez/maven/save-state/images/download.svg) ](https://bintray.com/prototypez/maven/save-state/_latestVersion) 3 | 4 | 5 | ![](https://raw.githubusercontent.com/PrototypeZ/SaveState/master/logo.png) 6 | 7 | 8 | 自动恢复 Activity、Fragment 以及 View 的状态。 9 | 10 | 无需任何类似 `onSaveInstanceState` 以及 `onRestoreInstanceState` 的模板代码。 11 | 12 | ## 如何使用 13 | 14 | 在成员变量上标记 `@AutoRestore` 注解。 15 | 16 | #### 在 Activity 中使用: 17 | 18 | ```kotlin 19 | class MyActivity : Activity() { 20 | 21 | @AutoRestore 22 | var myInt: Int = 0; 23 | 24 | @AutoRestore 25 | var myRpcCall: IBinder? = null; 26 | 27 | @AutoRestore 28 | var result: String? = null; 29 | 30 | override fun onCreate(savedInstanceState: Bundle?) { 31 | // Your code here 32 | } 33 | } 34 | ``` 35 | 36 | #### 在 Fragment 中使用: 37 | 38 | 39 | ```kotlin 40 | class MyFragment : Fragment() { 41 | 42 | @AutoRestore 43 | var currentLoginUser: User? = null; 44 | 45 | @AutoRestore 46 | var networkResponse: List>? = null; 47 | 48 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 49 | // Your code here 50 | } 51 | } 52 | ``` 53 | 54 | 55 | #### 在自定义 View 中使用: 56 | 57 | 58 | ```kotlin 59 | class MyView : FrameLayout { 60 | 61 | @AutoRestore 62 | val someText: String? = null; 63 | 64 | @AutoRestore 65 | val size: Size? = null; 66 | 67 | @AutoRestore 68 | val myFloatArray: FloatArray? = null; 69 | 70 | constructor(context: Context) : super(context) { 71 | // your code here 72 | } 73 | 74 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { 75 | // your code here 76 | } 77 | 78 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 79 | // your code here 80 | } 81 | 82 | } 83 | ``` 84 | 85 | 没错,就这么简单,只需要在变量上标记 `@AutoRestore` 注解。 86 | 87 | ## 现在就接入 SaveState 88 | 89 | 在项目根目录的 `build.gradle` 中增加以下内容: 90 | 91 | ```groovy 92 | buildscript { 93 | 94 | repositories { 95 | google() 96 | jcenter() 97 | } 98 | dependencies { 99 | // your other dependencies 100 | 101 | // dependency for save-state 102 | classpath "io.github.prototypez:save-state:${latest_version}" 103 | } 104 | } 105 | ``` 106 | 107 | SaveState 当前最新版本: [ ![Download](https://api.bintray.com/packages/prototypez/maven/save-state/images/download.svg) ](https://bintray.com/prototypez/maven/save-state/_latestVersion) 108 | 109 | 然后在您的项目的 **application** 模块的 `build.gradle` 中应用插件: 110 | ```groovy 111 | apply plugin: 'com.android.application' 112 | apply plugin: 'save.state' 113 | ``` 114 | 115 | 如果您的模块包含 `kotlin` 代码, 请确保 `kotlin-kapt` 插件也同步导入: 116 | ```groovy 117 | apply plugin: 'com.android.application' 118 | apply plugin: 'kotlin-android' 119 | apply plugin: 'kotlin-kapt' 120 | apply plugin: 'save.state' 121 | ``` 122 | 123 | 如果你的项目中还有其他 **library** 模块也需要使用 SaveState,那么只需要在对应模块的 `build.gradle` 中也应用插件即可: 124 | 125 | ```groovy 126 | apply plugin: 'com.android.library' 127 | apply plugin: 'save.state' 128 | ``` 129 | 130 | 如果 **library** 模块也包含 `kotlin` 代码,那和 **application** 模块类似: 131 | ```groovy 132 | apply plugin: 'com.android.library' 133 | apply plugin: 'kotlin-android' 134 | apply plugin: 'kotlin-kapt' 135 | apply plugin: 'save.state' 136 | ``` 137 | 138 | 139 | > 注意事项:如果您的模块是纯 Java 模块,那么 SaveState 默认使用 `annotationProcessor`; 140 | 而如果你的模块包含 `kotlin` 代码,那么 SaveState 则会在编译时使用 `kotlin-kapt` 插件。 141 | 所以如果您的模块包含 `kotlin` 代码,同时又使用 SaveState 插件的情况下, 142 | 请保证其他注解处理框架统一使用 `kapt` 插件。 143 | 例如:Dagger, DeepLinkDispatch 的写法应改造为: 144 | > ```groovy 145 | > kapt "com.google.dagger:dagger-compiler:${dagger_version}" 146 | > kapt "com.airbnb:deeplinkdispatch-processor:${deeplinkdispatch_version}" 147 | > ``` 148 | 149 | ## 支持的变量类型 150 | 151 | 如果被 `@AutoRestore` 标记的字段是下列类型之一,那么不需要额外的配置, SaveState 就可以帮您自动保存与恢复变量。 152 | 153 | 154 | 基本数据类型(包装类型) | 对象 | 数组 155 | -----------------------|----------------|------- 156 | int/Integer | Serializable | byte[] 157 | long/Long | IBinder | short[] 158 | short/Short | Bundle | char[] 159 | float/Float | CharSequence | float[] 160 | double/Double | Parcelable | CharSequence[] 161 | byte/Byte | Size | Parcelable[] 162 | char/Character | SizeF | 163 | boolean/Boolean | String | 164 | 165 | ## 自定义变量类型 166 | 167 | 如果您需要自动保存与恢复的变量不属于上面类型中的任意一种,并且您的变量类型可以被序列化为 `JSON` , 168 | 那么 SaveState 可以通过把这个对象和与它对应的 `JSON` 字符串之间的序列化和反序列化操作, 来实现变量的自动保存与恢复。 169 | 170 | 例如自定义对象: 171 | 172 | ```kotlin 173 | class User ( 174 | val name: String, 175 | val age: Int 176 | ) 177 | 178 | 179 | class NetworkResponse ( 180 | val resultCode: Int, 181 | val data: T? 182 | ) 183 | ``` 184 | 185 | 类似这样的对象都可以通过 SaveState 来自动恢复: 186 | 187 | ```kotlin 188 | class MyActivity : Activity() { 189 | 190 | @AutoRestore 191 | var user: User? = null 192 | 193 | @AutoRestore 194 | var response: NetworkResponse>? = null 195 | } 196 | ``` 197 | 198 | 额外的配置操作有: 199 | 200 | 1. 确保项目中已引入 **支持的`JSON`序列化库** 之一 201 | 2. 在模块( **com.android.application** / **com.android.library** )的 `build.gradle` 中加入配置, 202 | 203 | 如果是纯 Java 模块: 204 | ```groovy 205 | defaultConfig { 206 | 207 | // your other configs 208 | 209 | // 配置 JSON 序列化库 210 | javaCompileOptions { 211 | annotationProcessorOptions { 212 | arguments = [ serializer : "/*JSON库*/" ] 213 | } 214 | } 215 | } 216 | ``` 217 | 218 | 如果是启用了 `kotlin` 的模块: 219 | ```groovy 220 | kapt { 221 | arguments { 222 | arg("serializer", "/*JSON库*/") 223 | } 224 | } 225 | ``` 226 | 227 | 228 | 目前支持的 `JSON` 序列化库有: 229 | 230 | + [gson](https://github.com/google/gson) 231 | + [fastjson](https://github.com/alibaba/fastjson) 232 | + [jackson](https://github.com/FasterXML/jackson) 233 | 234 | ## FAQ 235 | 236 | + Q: SaveState 支持 Instant Run 吗? 237 | 238 | A: 是的,基于 Transform API, 所以支持。 239 | 240 | + Q: 需要配置 Proguard 混淆规则吗? 241 | 242 | A: 没有使用任何反射,不需要额外配置。 243 | 244 | + Q: SaveState 性能如何? 245 | 246 | A: 当前版本基于编译时字节码修改以及 AnnotationProcessor,所以运行时性能几乎和手写是一样的,编译时因为插入了额外的任务,会稍微影响编译速度,但是根据实测,这点影响是可以忽略不计的。 247 | 248 | + Q: SaveState 大吗?会影响打包出来 APK 大小吗? 249 | 250 | A: SaveState 主要工作都在编译时完成,运行时没有任何依赖,不用担心影响 APK 大小。 251 | 252 | ## LICENSE 253 | 254 | Copyright (c) 2016-present, SateState Contributors. 255 | 256 | Licensed under the Apache License, Version 2.0 (the "License"); 257 | you may not use this file except in compliance with the License. 258 | You may obtain a copy of the License at 259 | 260 | http://www.apache.org/licenses/LICENSE-2.0 261 | 262 | Unless required by applicable law or agreed to in writing, software 263 | distributed under the License is distributed on an "AS IS" BASIS, 264 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 265 | See the License for the specific language governing permissions and 266 | limitations under the License. -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | apply plugin: 'save.state' 6 | 7 | android { 8 | compileSdkVersion 27 9 | defaultConfig { 10 | applicationId "savestate.prototype.github.io.savestate" 11 | minSdkVersion 15 12 | targetSdkVersion 27 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | 17 | } 18 | 19 | dataBinding { 20 | enabled = true 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | targetCompatibility 1.8 31 | sourceCompatibility 1.8 32 | } 33 | } 34 | 35 | kapt { 36 | arguments { 37 | arg("serializer", "fastjson") 38 | } 39 | } 40 | 41 | dependencies { 42 | implementation fileTree(dir: 'libs', include: ['*.jar']) 43 | implementation 'com.android.support:appcompat-v7:27.1.1' 44 | implementation 'com.google.code.gson:gson:2.8.4' 45 | implementation 'com.alibaba:fastjson:1.1.68.android' 46 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.10' 47 | implementation 'com.fasterxml.jackson.core:jackson-core:2.8.10' 48 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 49 | testImplementation 'junit:junit:4.12' 50 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 51 | kapt "androidx.databinding:databinding-compiler:3.2.1" 52 | 53 | implementation project(':kotlinModule') 54 | implementation project(':javaModule') 55 | 56 | // kapt project(':processor') 57 | // implementation project(':core') 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/savestate/prototype/github/io/io/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package savestate.prototype.github.io.io; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("savestate.prototype.github.io.savestate", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/io/github/prototypez/savestate/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package io.github.prototypez.savestate.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.databinding.DataBindingUtil; 6 | import android.os.Bundle; 7 | import android.support.annotation.Nullable; 8 | import android.support.v7.app.AppCompatActivity; 9 | 10 | import io.github.prototypez.savestate.R; 11 | import io.github.prototypez.savestate.core.annotation.AutoRestore; 12 | import io.github.prototypez.savestate.databinding.ActivityMainBinding; 13 | import io.github.prototypez.savestate.kotlin.activity.KotlinActivity; 14 | import io.github.prototypez.savestate.kotlin.activity.KotlinFragmentActivity; 15 | import io.github.prototypez.savestate.kotlin.activity.KotlinViewActivity; 16 | import io.github.prototypez.savestate.plain.activity.JavaActivity; 17 | import io.github.prototypez.savestate.plain.activity.JavaFragmentActivity; 18 | import io.github.prototypez.savestate.plain.activity.JavaViewActivity; 19 | 20 | public class MainActivity extends Activity { 21 | 22 | ActivityMainBinding mBinding; 23 | 24 | @AutoRestore 25 | String lastClick; 26 | 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); 31 | 32 | mBinding.javaActivity.setOnClickListener(v -> { 33 | Intent intent = new Intent(this, JavaActivity.class); 34 | startActivity(intent); 35 | this.lastClick = "javaActivity"; 36 | showLastClick(); 37 | }); 38 | 39 | mBinding.javaFragment.setOnClickListener(v -> { 40 | Intent intent = new Intent(this, JavaFragmentActivity.class); 41 | startActivity(intent); 42 | this.lastClick = "javaFragment"; 43 | showLastClick(); 44 | }); 45 | 46 | mBinding.javaView.setOnClickListener(v -> { 47 | Intent intent = new Intent(this, JavaViewActivity.class); 48 | startActivity(intent); 49 | this.lastClick = "javaView"; 50 | showLastClick(); 51 | }); 52 | 53 | mBinding.kotlinActivity.setOnClickListener(v -> { 54 | Intent intent = new Intent(this, KotlinActivity.class); 55 | startActivity(intent); 56 | this.lastClick = "kotlinActivity"; 57 | showLastClick(); 58 | }); 59 | 60 | mBinding.kotlinFragment.setOnClickListener(v -> { 61 | Intent intent = new Intent(this, KotlinFragmentActivity.class); 62 | startActivity(intent); 63 | this.lastClick = "kotlinFragment"; 64 | showLastClick(); 65 | }); 66 | 67 | mBinding.kotlinView.setOnClickListener(v -> { 68 | Intent intent = new Intent(this, KotlinViewActivity.class); 69 | startActivity(intent); 70 | this.lastClick = "kotlinView"; 71 | showLastClick(); 72 | }); 73 | 74 | mBinding.smartKotlinActivity.setOnClickListener(v -> { 75 | Intent intent = new Intent(this, SmartKotlinActivity.class); 76 | startActivity(intent); 77 | this.lastClick = "kotlinActivityInApp"; 78 | showLastClick(); 79 | }); 80 | 81 | showLastClick(); 82 | } 83 | 84 | 85 | private void showLastClick() { 86 | mBinding.history.setText(String.format("Last click: %s", this.lastClick)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/io/github/prototypez/savestate/activity/SmartKotlinActivity.kt: -------------------------------------------------------------------------------- 1 | package io.github.prototypez.savestate.activity 2 | 3 | import android.support.v7.app.AppCompatActivity 4 | import android.os.Bundle 5 | import io.github.prototypez.savestate.R 6 | import io.github.prototypez.savestate.core.annotation.AutoRestore 7 | import kotlinx.android.synthetic.main.activity_smart_kotlin.*; 8 | 9 | class SmartKotlinActivity : AppCompatActivity() { 10 | 11 | @AutoRestore 12 | var a: Int = 0 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_smart_kotlin) 17 | text.text = a.toString() 18 | 19 | assign_value.setOnClickListener { 20 | a = 100 21 | text.text = a.toString() 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 16 | 17 |