latest visit record

This commit is contained in:
cgspine
2019-08-05 14:11:40 +08:00
parent a612cb4a32
commit 701afa2cda
14 changed files with 194 additions and 164 deletions
@@ -8,7 +8,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface BoolArgument {
String name();
boolean defaultValue();
String[] names();
}
@@ -8,6 +8,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface FloatArgument {
String name();
float defaultValue();
String[] names();
}
@@ -8,6 +8,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface IntArgument {
String name();
int defaultValue();
String[] names();
}
@@ -8,6 +8,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface LongArgument {
String name();
long defaultValue();
String[] names();
}
@@ -8,6 +8,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface StringArgument {
String name();
String defaultValue();
String[] names();
}
@@ -17,7 +17,9 @@ import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.Processor;
@@ -28,6 +30,8 @@ import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javafx.util.Pair;
@AutoService(Processor.class)
public class LatestVisitProcessor extends BaseProcessor {
@@ -75,29 +79,40 @@ public class LatestVisitProcessor extends BaseProcessor {
|| isSubtypeOfType(elementType, QMUI_FRAGMENT_TYPE)
|| isSubtypeOfType(elementType, QMUI_ACTIVITY_TYPE)) {
ClassName elementName = ClassName.get(classElement);
BoolArgument[] boolArguments = element.getAnnotationsByType(BoolArgument.class);
FloatArgument[] floatArguments = element.getAnnotationsByType(FloatArgument.class);
LongArgument[] longArguments = element.getAnnotationsByType(LongArgument.class);
IntArgument[] intArguments = element.getAnnotationsByType(IntArgument.class);
StringArgument[] stringArguments = element.getAnnotationsByType(StringArgument.class);
int totalArgumentsCount = 0;
if (!isNullOrEmpty(boolArguments)) {
totalArgumentsCount += boolArguments.length;
List<Pair<String, String>> nameAndTypeList = new ArrayList<>();
BoolArgument boolAnnotation = element.getAnnotation(BoolArgument.class);
if (boolAnnotation != null) {
for (String name : boolAnnotation.names()) {
nameAndTypeList.add(new Pair<>(name, "Boolean"));
}
}
if (!isNullOrEmpty(floatArguments)) {
totalArgumentsCount += floatArguments.length;
FloatArgument floatArguments = element.getAnnotation(FloatArgument.class);
if (floatArguments != null) {
for (String name : floatArguments.names()) {
nameAndTypeList.add(new Pair<>(name, "Float"));
}
}
if (!isNullOrEmpty(longArguments)) {
totalArgumentsCount += longArguments.length;
LongArgument longArguments = element.getAnnotation(LongArgument.class);
if (longArguments != null) {
for (String name : longArguments.names()) {
nameAndTypeList.add(new Pair<>(name, "Long"));
}
}
if (!isNullOrEmpty(intArguments)) {
totalArgumentsCount += intArguments.length;
IntArgument intArguments = element.getAnnotation(IntArgument.class);
if (intArguments != null) {
for (String name : intArguments.names()) {
nameAndTypeList.add(new Pair<>(name, "Integer"));
}
}
if (!isNullOrEmpty(stringArguments)) {
totalArgumentsCount += stringArguments.length;
StringArgument stringArguments = element.getAnnotation(StringArgument.class);
if (stringArguments != null) {
for (String name : stringArguments.names()) {
nameAndTypeList.add(new Pair<>(name, "String"));
}
}
if (totalArgumentsCount == 0) {
if (nameAndTypeList.size() == 0) {
constructorBuilder.addStatement("$T record$L = new $T($L, $T.class, null)",
RecordMetaName, currentId, RecordMetaName, currentId, elementName);
} else {
@@ -106,61 +121,16 @@ public class LatestVisitProcessor extends BaseProcessor {
RecordMetaName, currentId, RecordMetaName, currentId,
elementName, RecordMetaArgumentName);
builder.indent();
int i;
if (!isNullOrEmpty(boolArguments)) {
BoolArgument arg;
for (i = 0; i < boolArguments.length; i++) {
arg = boolArguments[i];
builder.add("new $T($S, Boolean.class, $L)",
RecordMetaArgumentName, arg.name(), arg.defaultValue());
if(--totalArgumentsCount > 0){
builder.add(",\n");
}
}
}
if (totalArgumentsCount > 0 && !isNullOrEmpty(intArguments)) {
IntArgument arg;
for (i = 0; i < intArguments.length; i++) {
arg = intArguments[i];
builder.add("new $T($S, Integer.class, $L)",
RecordMetaArgumentName, arg.name(), arg.defaultValue());
if(--totalArgumentsCount > 0){
builder.add(",\n");
}
}
}
if (totalArgumentsCount > 0 && !isNullOrEmpty(longArguments)) {
LongArgument arg;
for (i = 0; i < longArguments.length; i++) {
arg = longArguments[i];
builder.add("new $T($S, Long.class, Long.valueOf($L))",
RecordMetaArgumentName, arg.name(), arg.defaultValue());
if(--totalArgumentsCount > 0){
builder.add(",\n");
}
}
}
if (totalArgumentsCount >0 && !isNullOrEmpty(floatArguments)) {
FloatArgument arg;
for (i = 0; i < floatArguments.length; i++) {
arg = floatArguments[i];
builder.add("new $T($S, Float.class, Float.valueOf((float)$L))",
RecordMetaArgumentName, arg.name(), arg.defaultValue());
if(--totalArgumentsCount > 0){
builder.add(",\n");
}
}
}
if (totalArgumentsCount > 0 && !isNullOrEmpty(stringArguments)) {
StringArgument arg;
for (i = 0; i < stringArguments.length; i++) {
arg = stringArguments[i];
builder.add("new $T($S, $T.class, $S)",
RecordMetaArgumentName, arg.name(), StringName, arg.defaultValue());
if(--totalArgumentsCount > 0){
builder.add(",\n");
}
String name;
String type;
for (int i = 0; i < nameAndTypeList.size(); i++) {
name = nameAndTypeList.get(i).getKey();
type = nameAndTypeList.get(i).getValue();
builder.add("new $T($S, $L.class)", RecordMetaArgumentName, name, type);
if (i < nameAndTypeList.size() - 1) {
builder.add(",\n");
}
}
builder.unindent();
builder.add("\n});");
@@ -204,11 +174,6 @@ public class LatestVisitProcessor extends BaseProcessor {
return true;
}
private <T> boolean isNullOrEmpty(T[] array) {
return array == null || array.length == 0;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
@@ -4,7 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.support.annotation.MainThread;
import com.qmuiteam.qmui.arch.record.DefaultLatestVisitStorage;
import com.qmuiteam.qmui.arch.record.LatestVisitArgumentSaver;
@@ -13,7 +13,8 @@ import com.qmuiteam.qmui.arch.record.RecordInfo;
import com.qmuiteam.qmui.arch.record.RecordMeta;
import com.qmuiteam.qmui.arch.record.RecordMetaMap;
import androidx.annotation.MainThread;
import java.util.ArrayList;
import java.util.List;
public class QMUILatestVisit {
private static QMUILatestVisit sInstance;
@@ -61,26 +62,19 @@ public class QMUILatestVisit {
return mStorage;
}
public RecordMeta getRecordMetaById(int id) {
return mRecordMap.getRecordMetaById(id);
}
@SuppressWarnings("unchecked")
private Intent getLatestVisitIntent(Context context) {
int activityId = getStorage().getActivityRecordId();
if (activityId == QMUILatestVisitStorage.NOT_EXIST) {
Log.i("cgine", "1");
return null;
}
RecordMeta activityMeta = mRecordMap.getRecordMetaById(activityId);
if (activityMeta == null) {
Log.i("cgine", "2");
return null;
}
Class<?> activityCls = activityMeta.getClazz();
Intent intent;
if (QMUIFragmentActivity.class.isAssignableFrom(activityCls)) {
Log.i("cgine", "3");
int fragmentId = getStorage().getFragmentRecordId();
if (fragmentId == QMUILatestVisitStorage.NOT_EXIST) {
return null;
@@ -109,17 +103,31 @@ public class QMUILatestVisit {
for (RecordMeta.ArgumentType argumentMeta : argumentTypes) {
String name = argumentMeta.getName();
Class<?> type = argumentMeta.getType();
Object defaultValue = argumentMeta.getDefaultValue();
if (type == Integer.TYPE || type == Integer.class) {
intent.putExtra(name, storage.getActivityIntArgument(name, (Integer) defaultValue));
Integer value = storage.getActivityIntArgument(name);
if (value != null) {
intent.putExtra(name, value);
}
} else if (type == Boolean.TYPE || type == Boolean.class) {
intent.putExtra(name, storage.getActivityBoolArgument(name, (Boolean) defaultValue));
Boolean value = storage.getActivityBoolArgument(name);
if (value != null) {
intent.putExtra(name, value);
}
} else if (type == Long.TYPE || type == Long.class) {
intent.putExtra(name, storage.getActivityLongArgument(name, (Long) defaultValue));
Long value = storage.getActivityLongArgument(name);
if (value != null) {
intent.putExtra(name, value);
}
} else if (type == Float.TYPE || type == Float.class) {
intent.putExtra(name, storage.getActivityFloatArgument(name, (Float) defaultValue));
Float value = storage.getActivityFloatArgument(name);
if (value != null) {
intent.putExtra(name, value);
}
} else if (type == String.class) {
intent.putExtra(name, storage.getActivityStringArgument(name, (String) defaultValue));
String value = storage.getActivityStringArgument(name);
if (value != null) {
intent.putExtra(name, value);
}
}
}
}
@@ -133,17 +141,32 @@ public class QMUILatestVisit {
for (RecordMeta.ArgumentType argumentMeta : argumentTypes) {
String name = argumentMeta.getName();
Class<?> type = argumentMeta.getType();
Object defaultValue = argumentMeta.getDefaultValue();
if (type == Integer.TYPE || type == Integer.class) {
bundle.putInt(name, storage.getFragmentIntArgument(name, (Integer) defaultValue));
Integer value = storage.getFragmentIntArgument(name);
if (value != null) {
bundle.putInt(name, value);
}
} else if (type == Boolean.TYPE || type == Boolean.class) {
bundle.putBoolean(name, storage.getFragmentBoolArgument(name, (Boolean) defaultValue));
Boolean value = storage.getFragmentBoolArgument(name);
if (value != null) {
bundle.putBoolean(name, value);
}
} else if (type == Long.TYPE || type == Long.class) {
bundle.putLong(name, storage.getFragmentLongArgument(name, (Long) defaultValue));
Long value = storage.getFragmentLongArgument(name);
if (value != null) {
bundle.putLong(name, value);
}
} else if (type == Float.TYPE || type == Float.class) {
bundle.putFloat(name, storage.getFragmentFloatArgument(name, (Float) defaultValue));
Float value = storage.getFragmentFloatArgument(name);
if (value != null) {
bundle.putFloat(name, value);
}
} else if (type == String.class) {
bundle.putString(name, storage.getFragmentStringArgument(name, (String) defaultValue));
String value = storage.getFragmentStringArgument(name);
if (value != null) {
bundle.putString(name, value);
}
}
}
return bundle;
@@ -168,26 +191,38 @@ public class QMUILatestVisit {
if (argumentTypes == null || argumentTypes.length == 0) {
recordInfo = new RecordInfo(meta.getId(), cls, null);
} else {
RecordInfo.Argument[] arguments = new RecordInfo.Argument[argumentTypes.length];
for (int i = 0; i < arguments.length; i++) {
RecordMeta.ArgumentType argMeta = argumentTypes[i];
List<RecordInfo.Argument> arguments = new ArrayList<>();
for (RecordMeta.ArgumentType argMeta : argumentTypes) {
String argName = argMeta.getName();
Class<?> argMetaType = argMeta.getType();
Object argValue = argumentSaver.getArgumentValueForLatestVisit(argName);
if(argValue instanceof Double){
argValue = ((Double) argValue).floatValue();
}
if (argValue == null) {
argValue = argMeta.getDefaultValue();
} else if (argValue.getClass() != argMetaType) {
continue;
}
// compatibility type conversion
if (argMetaType == Long.TYPE || argMeta.getType() == Long.class) {
if (argValue instanceof Integer) {
argValue = ((Integer) argValue).longValue();
}
} else if (argMetaType == Float.TYPE || argMeta.getType() == Float.class) {
if (argValue instanceof Double) {
argValue = ((Double) argValue).floatValue();
} else if (argValue instanceof Integer) {
argValue = ((Integer) argValue).floatValue();
}
}
if (argValue.getClass() != argMetaType) {
throw new RuntimeException(String.format("The argument value type(%s) for %s " +
"not match the type provided by annotation(%s).",
argValue.getClass().getSimpleName(), argName, argMetaType.getSimpleName()));
}
RecordInfo.Argument argument = new RecordInfo.Argument(argName, argMetaType, argValue);
arguments[i] = argument;
arguments.add(argument);
}
recordInfo = new RecordInfo(meta.getId(), cls, arguments);
recordInfo = new RecordInfo(meta.getId(), cls,
arguments.toArray(new RecordInfo.Argument[0]));
}
return recordInfo;
}
@@ -26,28 +26,44 @@ public class DefaultLatestVisitStorage implements QMUILatestVisitStorage {
}
@Override
public String getFragmentStringArgument(String key, String defValue) {
return sp.getString(SP_FRAGMENT_ARG_PREFIX + key, defValue);
public String getFragmentStringArgument(String key) {
return sp.getString(SP_FRAGMENT_ARG_PREFIX + key, null);
}
@Override
public int getFragmentIntArgument(String key, int defValue) {
return sp.getInt(SP_FRAGMENT_ARG_PREFIX + key, defValue);
public Integer getFragmentIntArgument(String key) {
String realKey = SP_FRAGMENT_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getInt(realKey, 0);
}
return null;
}
@Override
public long getFragmentLongArgument(String key, long defValue) {
return sp.getLong(SP_FRAGMENT_ARG_PREFIX + key, defValue);
public Long getFragmentLongArgument(String key) {
String realKey = SP_FRAGMENT_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getLong(realKey, 0);
}
return null;
}
@Override
public float getFragmentFloatArgument(String key, float defValue) {
return sp.getFloat(SP_FRAGMENT_ARG_PREFIX + key, defValue);
public Float getFragmentFloatArgument(String key) {
String realKey = SP_FRAGMENT_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getFloat(realKey, 0);
}
return null;
}
@Override
public boolean getFragmentBoolArgument(String key, boolean defValue) {
return sp.getBoolean(SP_FRAGMENT_ARG_PREFIX + key, defValue);
public Boolean getFragmentBoolArgument(String key) {
String realKey = SP_FRAGMENT_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getBoolean(realKey, false);
}
return null;
}
@@ -57,28 +73,44 @@ public class DefaultLatestVisitStorage implements QMUILatestVisitStorage {
}
@Override
public String getActivityStringArgument(String key, String defValue) {
return sp.getString(SP_ACTIVITY_ARG_PREFIX + key, defValue);
public String getActivityStringArgument(String key) {
return sp.getString(SP_ACTIVITY_ARG_PREFIX + key, null);
}
@Override
public int getActivityIntArgument(String key, int defValue) {
return sp.getInt(SP_ACTIVITY_ARG_PREFIX + key, defValue);
public Integer getActivityIntArgument(String key) {
String realKey = SP_ACTIVITY_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getInt(realKey, 0);
}
return null;
}
@Override
public long getActivityLongArgument(String key, long defValue) {
return sp.getLong(SP_ACTIVITY_ARG_PREFIX + key, defValue);
public Long getActivityLongArgument(String key) {
String realKey = SP_ACTIVITY_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getLong(realKey, 0);
}
return null;
}
@Override
public float getActivityFloatArgument(String key, float defValue) {
return sp.getFloat(SP_ACTIVITY_ARG_PREFIX + key, defValue);
public Float getActivityFloatArgument(String key) {
String realKey = SP_ACTIVITY_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getFloat(realKey, 0);
}
return null;
}
@Override
public boolean getActivityBoolArgument(String key, boolean defValue) {
return sp.getBoolean(SP_ACTIVITY_ARG_PREFIX + key, defValue);
public Boolean getActivityBoolArgument(String key) {
String realKey = SP_ACTIVITY_ARG_PREFIX + key;
if (sp.contains(realKey)) {
return sp.getBoolean(realKey, false);
}
return null;
}
@Override
@@ -11,15 +11,15 @@ public interface QMUILatestVisitStorage {
int getFragmentRecordId();
String getFragmentStringArgument(String key, String defValue);
String getFragmentStringArgument(String key);
int getFragmentIntArgument(String key, int defValue);
Integer getFragmentIntArgument(String key);
long getFragmentLongArgument(String key, long defValue);
Long getFragmentLongArgument(String key);
float getFragmentFloatArgument(String key, float defValue);
Float getFragmentFloatArgument(String key);
boolean getFragmentBoolArgument(String key, boolean defValue);
Boolean getFragmentBoolArgument(String key);
// Activity Stuff
@@ -27,13 +27,13 @@ public interface QMUILatestVisitStorage {
int getActivityRecordId();
String getActivityStringArgument(String key, String defValue);
String getActivityStringArgument(String key);
int getActivityIntArgument(String key, int defValue);
Integer getActivityIntArgument(String key);
long getActivityLongArgument(String key, long defValue);
Long getActivityLongArgument(String key);
float getActivityFloatArgument(String key, float defValue);
Float getActivityFloatArgument(String key);
boolean getActivityBoolArgument(String key, boolean defValue);
Boolean getActivityBoolArgument(String key);
}
@@ -3,6 +3,8 @@ package com.qmuiteam.qmui.arch.record;
import androidx.annotation.Nullable;
import java.util.Arrays;
public class RecordInfo {
private int mId;
private Class<?> mClazz;
@@ -32,7 +34,8 @@ public class RecordInfo {
return false;
}
RecordInfo other = (RecordInfo) obj;
return other.mId == mId && other.mClazz == mClazz;
return other.mId == mId && other.mClazz == mClazz &&
Arrays.equals(mArguments, other.mArguments);
}
public static class Argument {
@@ -27,12 +27,10 @@ public class RecordMeta {
public static class ArgumentType {
private String mName;
private Class<?> mType;
private Object mDefaultValue;
public ArgumentType(String name, Class<?> type, Object defaultValue){
public ArgumentType(String name, Class<?> type){
mName = name;
mType = type;
mDefaultValue = defaultValue;
}
public String getName() {
@@ -42,9 +40,5 @@ public class RecordMeta {
public Class<?> getType() {
return mType;
}
public Object getDefaultValue() {
return mDefaultValue;
}
}
}
@@ -37,7 +37,7 @@ import butterknife.ButterKnife;
*/
@LatestVisitRecord
@BoolArgument(name = "test_activity", defaultValue = false)
@BoolArgument(names = {"test_activity"})
public class TranslucentActivity extends BaseActivity {
@BindView(R.id.topbar) QMUITopBar mTopBar;
@@ -50,9 +50,9 @@ import butterknife.ButterKnife;
@Widget(name = "QMUIFragment", iconRes = R.mipmap.icon_grid_layout)
@LatestVisitRecord
@LongArgument(name = "test_long", defaultValue = 0L)
@FloatArgument(name = "test_float", defaultValue = 0)
@StringArgument(name = "test_string", defaultValue = "")
@LongArgument(names = {"test_long", "test_long1", "test_long2", "test_long3"})
@FloatArgument(names = "test_float")
@StringArgument(names = "test_string")
public class QDArchTestFragment extends BaseFragment {
private static final String TAG = "QDArchTestFragment";
private static final String ARG_INDEX = "arg_index";
@@ -116,7 +116,10 @@ public class QDArchTestFragment extends BaseFragment {
setFragmentResult(RESULT_OK, intent);
Bundle arguments = getArguments();
if(arguments != null && arguments.getLong("test_long") == 100
&& arguments.getFloat("test_float") == 100.13
&& arguments.getLong("test_long1") == 1000
&& arguments.getLong("test_long2") == 400
&& arguments.getLong("test_long3", 200) == 200
&& arguments.getFloat("test_float") == 100.13f
&& "你好".equals(arguments.getString("test_string"))){
Toast.makeText(getContext(), "恢复到最近阅读(Muti)", Toast.LENGTH_SHORT).show();
}
@@ -130,6 +133,10 @@ public class QDArchTestFragment extends BaseFragment {
return 100.13;
}else if("test_string".equals(argumentName)){
return "你好";
}else if("test_long1".equals(argumentName)){
return 1000;
}else if("test_long2".equals(argumentName)){
return 400;
}
return null;
}
@@ -45,7 +45,7 @@ import androidx.recyclerview.widget.RecyclerView;
@Widget(group = Group.Other, name = "webview + recyclerview")
@LatestVisitRecord
@IntArgument(name = "fragment_test", defaultValue = 0)
@IntArgument(names = "fragment_test")
public class QDContinuousNestedScroll1Fragment extends QDContinuousNestedScrollBaseFragment {
private QMUIWebView mNestedWebView;
@@ -56,7 +56,7 @@ public class QDContinuousNestedScroll1Fragment extends QDContinuousNestedScrollB
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if(arguments != null && arguments.getInt("fragment_test") == 20){
if (arguments != null && arguments.getInt("fragment_test") == 20) {
Toast.makeText(getContext(), "恢复到最近阅读(Int)", Toast.LENGTH_SHORT).show();
}
}
@@ -118,7 +118,7 @@ public class QDContinuousNestedScroll1Fragment extends QDContinuousNestedScrollB
@Override
public Object getArgumentValueForLatestVisit(String argumentName) {
if("fragment_test".equals(argumentName)){
if ("fragment_test".equals(argumentName)) {
return 20;
}
return null;