├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── nashlegend │ │ └── demo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── net │ │ │ └── nashlegend │ │ │ └── demo │ │ │ ├── App.java │ │ │ ├── MainActivity.java │ │ │ ├── Sample.java │ │ │ └── SampleSub.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── net │ └── nashlegend │ └── demo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── net │ │ └── nashlegend │ │ └── anypref │ │ ├── AnyPref.java │ │ ├── PrefUtil.java │ │ ├── SharedPrefs.java │ │ └── annotations │ │ ├── PrefArrayList.java │ │ ├── PrefField.java │ │ ├── PrefIgnore.java │ │ ├── PrefModel.java │ │ └── PrefSub.java │ └── test │ └── java │ └── net │ └── nashlegend │ └── anypref │ ├── AnyPrefTest.java │ ├── SharedPrefsTest.java │ └── model │ ├── Sample.java │ └── SubSample.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | /.idea 3 | .gradle 4 | /local.properties 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 一个SharedPreferences工具类 2 | 3 | [![](https://jitpack.io/v/NashLegend/AnyPref.svg)](https://jitpack.io/#NashLegend/AnyPref) 4 | 5 | 在工程根目录build.gradle添加jitpack: 6 | ```gradle 7 | allprojects { 8 | repositories { 9 | maven { url "https://jitpack.io" } 10 | } 11 | } 12 | ``` 13 | 14 | 在使用AnyPref的模块中添加: 15 | 16 | ```gradle 17 | dependencies { 18 | compile 'com.github.NashLegend:AnyPref:1.2.6' 19 | } 20 | ``` 21 | 22 | 在应用的Application的```onCreate()```中添加如下代码(主要是为了省却后面要传入Context参数的麻烦) 23 | 24 | ``` 25 | AnyPref.init(this); 26 | ``` 27 | 28 | ## 1. 读写实例对象 29 | 30 | 假设有一个Sample类(所有注解都是非必须的) 31 | 32 | ``` 33 | @PrefModel("prefName")//"prefName"表示保存SharedPreferences的name,可为任意String字符串,若不添加此注解则为类全名 34 | public class Sample { 35 | 36 | @PrefField("intFieldKey")//"intFieldKey"表示保存此值时的key,可为任意String字符串,若不添加此注解,则为此字段的字段名 37 | public int intField = 32; 38 | 39 | @PrefIgnore//添加此注解表示不保存这个字段 40 | public float floatField = 1.2345f; 41 | 42 | @PrefField(numDef = 110)//表示如果读取不到后使用的默认值 43 | public long longField = 95789465213L; 44 | 45 | public String stringField = "string"; 46 | 47 | @PrefField(boolDef = true) 48 | public boolean boolField = false; 49 | 50 | @PrefField(value = "setValueWithSpecifiedKey", strDef = {"1", "2", "3", "4"})//默认值是[1,2,3,4] 51 | public Set setValue = new LinkedHashSet<>(); 52 | 53 | @PrefSub(nullable = false)//nullable表示取子对象的时候,子对象是否可以为null,默认是true 54 | public SubSample son1;//标注了@PrefSub的字段,虽然不是SharedPreferences支持的类型,但是仍会被保存 55 | 56 | @PrefArrayList(nullable = true, itemNullable = true)//nullable同上,itemNullable表示列表中的数据是否可以为null,默认为true 57 | public ArrayList sampleArrayList;//标注了@PrefArrayList的ArrayList会被保存,必须要有泛型信息,且不能是基本类型的,其限制与PrefModel相同 58 | } 59 | ``` 60 | 61 | #### 保存数据: 62 | ``` 63 | AnyPref.put(sample); 64 | //或者 65 | AnyPref.put(sample, "your prefName");第二个参数是自己定义的保存此类的sharedPreferences name,不是PrefModel定义的那个name 66 | ``` 67 | 68 | #### 读取数据 69 | ``` 70 | Sample sample = AnyPref.get(Sample.class); 71 | //或者 72 | Sample sample = AnyPref.get(Sample.class, "your prefName"); 73 | //或者 74 | Sample sample = AnyPref.get(Sample.class, "your prefName", true);//第三个参数表示读取出来的对象是否可以为null,默认不为null 75 | ``` 76 | 77 | #### 清除数据 78 | ``` 79 | AnyPref.clear(Sample.class); 80 | //或者 81 | AnyPref.clear(Sample.class, "your prefName"); 82 | ``` 83 | 84 | 85 | PS,对于实例对象的读写: 86 | 87 | 0. 保存的对象必须支持无参构造函数,它是写代码时用到的Model对象或者一组Setting等,不是用来保存一些系统对象比如String,View的; 88 | 1. 保存的对象的字段们中只保存SharedPreferences支持的以及标注了```@PrefSub```和```@PrefArrayList```的字段; 89 | 2. 标注了```@PrefSub```和```@PrefArrayList```的类型要求同第一条 90 | 3. 只会保存修饰符为```public```的字段,```static```与```final```的字段均不会保存; 91 | 4. 不要有循环引用,标注了```@PrefSub```的对象中不要包含标注了```@PrefSub```的父对象的类,```@PrefArrayList```同理,否则会导致向下无限读取 92 | 93 | ##### 如果使用了ProGuard,在要保护的类上添加注解@PrefModel,然后在proguard配置文件中添加 94 | 95 | ``` 96 | -keepattributes Signature 97 | -keep class net.nashlegend.anypref.annotations.PrefModel 98 | -keepclasseswithmembernames @net.nashlegend.anypref.annotations.PrefModel class * { 99 | public ; 100 | } 101 | ``` 102 | 103 | ## 2. 读写任意数据 104 | 105 | ``` 106 | AnyPref.getPrefs("sample")//或者new SharedPrefs("sample") 107 | .putLong("long", 920394857382L) 108 | .putInt("int", 63) 109 | .putString("string", "sample string"); 110 | 111 | AnyPref.getPrefs(Sample.class) 112 | .beginTransaction() 113 | .putLong("long", 920394857382L) 114 | .putInt("int", 63) 115 | .putString("string", "sample string") 116 | .commit(); 117 | 118 | SharedPrefs sharedPrefs = AnyPref.getPrefs("sample"); 119 | System.out.println(sharedPrefs.getInt("int", 0)); 120 | System.out.println(sharedPrefs.getLong("long", 0)); 121 | System.out.println(sharedPrefs.getString("string", "")); 122 | ``` 123 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | applicationId "net.nashlegend.anypref" 9 | minSdkVersion 11 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | debug { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | testCompile 'junit:junit:4.12' 29 | compile 'com.android.support:appcompat-v7:23.4.0' 30 | compile project(':library') 31 | // compile 'com.github.NashLegend:AnyPref:1.0.0' 32 | } 33 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Pan/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -keepclasseswithmembernames class net.nashlegend.demo.Sample { 20 | public ; 21 | } 22 | 23 | -keepclasseswithmembernames class net.nashlegend.demo.SampleSon { 24 | public ; 25 | } 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/net/nashlegend/demo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.nashlegend.demo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/nashlegend/demo/App.java: -------------------------------------------------------------------------------- 1 | package net.nashlegend.demo; 2 | 3 | import android.app.Application; 4 | 5 | import net.nashlegend.anypref.AnyPref; 6 | 7 | /** 8 | * Created by NashLegend on 16/5/23. 9 | */ 10 | public class App extends Application { 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | AnyPref.init(this); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/net/nashlegend/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package net.nashlegend.demo; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import net.nashlegend.anypref.AnyPref; 10 | import net.nashlegend.anypref.SharedPrefs; 11 | 12 | import java.lang.reflect.Field; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | Button button = (Button) findViewById(R.id.btn); 21 | assert button != null; 22 | button.setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | anyPref(); 26 | namedPref(); 27 | print(Sample.class); 28 | } 29 | }); 30 | } 31 | 32 | private void anyPref() { 33 | Sample sample = new Sample(); 34 | sample.boolField = true; 35 | sample.intField = 63; 36 | sample.floatField = 42.0f; 37 | sample.stringField = "sample string"; 38 | SampleSub son1 = new SampleSub(); 39 | son1.name = "son1"; 40 | SampleSub son2 = new SampleSub(); 41 | son2.name = "son2"; 42 | sample.son1 = son1; 43 | sample.son2 = son2; 44 | AnyPref.put(sample); 45 | Sample sampleOut = AnyPref.get(Sample.class); 46 | System.out.println("son1:" + sampleOut.son1.name); 47 | } 48 | 49 | private void namedPref() { 50 | AnyPref.getPrefs(getLocalClassName()) 51 | .putLong("long", 920394857382L) 52 | .putInt("int", 63) 53 | .putString("string", "sample string"); 54 | 55 | AnyPref.getPrefs(Sample.class) 56 | .beginTransaction() 57 | .putLong("long", 33333) 58 | .putInt("int", 22222) 59 | .putString("string", "sssss") 60 | .commit(); 61 | 62 | SharedPrefs sharedPrefs = AnyPref.getPrefs(getLocalClassName()); 63 | System.out.println(sharedPrefs.getInt("int", 0)); 64 | System.out.println(sharedPrefs.getLong("long", 0)); 65 | System.out.println(sharedPrefs.getString("string", "")); 66 | } 67 | 68 | private void print(Class clazz) { 69 | Field[] fieldArray = clazz.getFields(); 70 | for (Field field : fieldArray) { 71 | System.out.println(field.getName()); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/net/nashlegend/demo/Sample.java: -------------------------------------------------------------------------------- 1 | package net.nashlegend.demo; 2 | 3 | import net.nashlegend.anypref.annotations.PrefField; 4 | import net.nashlegend.anypref.annotations.PrefIgnore; 5 | import net.nashlegend.anypref.annotations.PrefModel; 6 | import net.nashlegend.anypref.annotations.PrefSub; 7 | 8 | import java.util.LinkedHashSet; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created by NashLegend on 16/5/22. 13 | */ 14 | @PrefModel("SampleKeys") 15 | public class Sample extends SampleSub { 16 | @PrefField("intKey") 17 | public int intField = 65535; 18 | @PrefIgnore 19 | public float floatField = 1.235f; 20 | public long longField = 95789465213L; 21 | public String stringField = "string"; 22 | public boolean boolField = false; 23 | public Set setValue = new LinkedHashSet<>(); 24 | public int intField2 = 65535; 25 | public float floatField2 = 1.235f; 26 | public long longField2 = 95789465213L; 27 | public String stringField2 = "string"; 28 | public boolean boolField2 = false; 29 | public Set setValue2 = new LinkedHashSet<>(); 30 | public int intField3 = 65535; 31 | public float floatField3 = 1.235f; 32 | public long longField3 = 95789465213L; 33 | public String stringField3 = "string"; 34 | public boolean boolField3 = false; 35 | public Set setValue3 = new LinkedHashSet<>(); 36 | 37 | @PrefField(numDef = 110) 38 | public long longField4 = 95789465213L; 39 | @PrefField(numDef = 110) 40 | public int intField4 = 2; 41 | @PrefField(numDef = 110) 42 | public float floatField4 = 1.2f; 43 | @PrefField(boolDef = true) 44 | public boolean boolField4 = false; 45 | @PrefField(strDef = "Default") 46 | public String stringField4 = "NotDefault"; 47 | 48 | private String pvString = "private"; 49 | private int pvInt = 10010; 50 | 51 | @PrefSub 52 | public SampleSub son1; 53 | 54 | public SampleSub son2; 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/net/nashlegend/demo/SampleSub.java: -------------------------------------------------------------------------------- 1 | package net.nashlegend.demo; 2 | 3 | import net.nashlegend.anypref.annotations.PrefField; 4 | import net.nashlegend.anypref.annotations.PrefIgnore; 5 | 6 | import java.util.LinkedHashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * Created by NashLegend on 16/6/2. 11 | */ 12 | public class SampleSub { 13 | 14 | @PrefField("intKey") 15 | public int subIntField = 65535; 16 | @PrefIgnore 17 | public float subFloatField = 1.235f; 18 | public long subLongField = 95789465213L; 19 | public String subStringField = "string"; 20 | public boolean subBoolField = false; 21 | public Set subSetValue = new LinkedHashSet<>(); 22 | public String name = "father"; 23 | 24 | public Sample sample;//如果SampleSub也有一个标记了PrefSub的Sample,就发生死循环 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 |