From 03c5a0b97a92061759583ecc623eab04eadabb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A3=E7=BA=AC?= Date: Thu, 26 Oct 2017 12:35:33 +0800 Subject: [PATCH] Support nested object type. --- .../android/arouter/demo/MainActivity.java | 12 +++++++++ .../demo/testactivity/Test1Activity.java | 15 +++++++++-- .../demo/testservice/JsonServiceImpl.java | 7 ++++++ .../arouter/facade/model/TypeWrapper.java | 25 +++++++++++++++++++ .../facade/service/SerializationService.java | 25 +++++++++++++++---- .../processor/AutowiredProcessor.java | 18 ++++++------- gradle.properties | 6 ++--- 7 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 arouter-annotation/src/main/java/com/alibaba/android/arouter/facade/model/TypeWrapper.java diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java b/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java index 15659029..8126cd5a 100644 --- a/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java +++ b/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java @@ -20,6 +20,11 @@ import com.alibaba.android.arouter.facade.callback.NavCallback; import com.alibaba.android.arouter.launcher.ARouter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static Activity activity; @@ -126,6 +131,11 @@ public void onInterrupt(Postcard postcard) { case R.id.autoInject: TestParcelable testParcelable = new TestParcelable("jack", 666); TestObj testObj = new TestObj("Rose", 777); + List objList = new ArrayList<>(); + objList.add(testObj); + + Map> map = new HashMap<>(); + map.put("testMap", objList); ARouter.getInstance().build("/test/activity1") .withString("name", "老王") @@ -135,6 +145,8 @@ public void onInterrupt(Postcard postcard) { .withString("url", "https://a.b.c") .withParcelable("pac", testParcelable) .withObject("obj", testObj) + .withObject("objList", objList) + .withObject("map", map) .navigation(); break; case R.id.navByName: diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java index 21ad9a1c..477b9370 100644 --- a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java @@ -12,6 +12,9 @@ import com.alibaba.android.arouter.facade.annotation.Route; import com.alibaba.android.arouter.launcher.ARouter; +import java.util.List; +import java.util.Map; + /** * https://m.aliyun.com/test/activity1?name=老王&age=23&boy=true&high=180 */ @@ -45,6 +48,12 @@ public class Test1Activity extends AppCompatActivity { @Autowired TestObj obj; + @Autowired + List objList; + + @Autowired + Map> map; + private long high; @Autowired @@ -68,7 +77,7 @@ protected void onCreate(Bundle savedInstanceState) { // url = getIntent().getStringExtra("url"); String params = String.format( - "name=%s,\n age=%s, \n height=%s,\n girl=%s,\n high=%s,\n url=%s,\n pac=%s,\n obj=%s \n ch=%s \n fl = %s, \n dou = %s", + "name=%s,\n age=%s, \n height=%s,\n girl=%s,\n high=%s,\n url=%s,\n pac=%s,\n obj=%s \n ch=%s \n fl = %s, \n dou = %s, \n objList=%s, \n map=%s", name, age, height, @@ -79,7 +88,9 @@ protected void onCreate(Bundle savedInstanceState) { obj, ch, fl, - dou + dou, + objList, + map ); helloService.sayHello("Hello moto."); diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testservice/JsonServiceImpl.java b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/JsonServiceImpl.java index 64c4ed27..3358c6bb 100644 --- a/app/src/main/java/com/alibaba/android/arouter/demo/testservice/JsonServiceImpl.java +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/JsonServiceImpl.java @@ -6,6 +6,8 @@ import com.alibaba.android.arouter.facade.service.SerializationService; import com.alibaba.fastjson.JSON; +import java.lang.reflect.Type; + /** * Used for json converter * @@ -29,4 +31,9 @@ public T json2Object(String text, Class clazz) { public String object2Json(Object instance) { return JSON.toJSONString(instance); } + + @Override + public T parseObject(String input, Type clazz) { + return JSON.parseObject(input, clazz); + } } diff --git a/arouter-annotation/src/main/java/com/alibaba/android/arouter/facade/model/TypeWrapper.java b/arouter-annotation/src/main/java/com/alibaba/android/arouter/facade/model/TypeWrapper.java new file mode 100644 index 00000000..41f21db9 --- /dev/null +++ b/arouter-annotation/src/main/java/com/alibaba/android/arouter/facade/model/TypeWrapper.java @@ -0,0 +1,25 @@ +package com.alibaba.android.arouter.facade.model; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Used for get type of target object. + * + * @author Alex Contact me. + * @version 1.0 + * @since 17/10/26 11:56:22 + */ +public class TypeWrapper { + protected final Type type; + + protected TypeWrapper() { + Type superClass = getClass().getGenericSuperclass(); + + type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; + } + + public Type getType() { + return type; + } +} diff --git a/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/SerializationService.java b/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/SerializationService.java index 46fc81f4..7c9a7e88 100644 --- a/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/SerializationService.java +++ b/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/SerializationService.java @@ -2,6 +2,8 @@ import com.alibaba.android.arouter.facade.template.IProvider; +import java.lang.reflect.Type; + /** * Used for parse json string. * @@ -10,20 +12,33 @@ * @since 2017/4/10 下午1:43 */ public interface SerializationService extends IProvider { + /** - * Parse json object. + * Parse json to object + * + * USE @parseObject PLEASE * - * @param json json str + * @param input json string * @param clazz object type - * @param type - * @return instance + * @return instance of object */ - T json2Object(String json, Class clazz); + @Deprecated + T json2Object(String input, Class clazz); /** * Object to json + * * @param instance obj * @return json string */ String object2Json(Object instance); + + /** + * Parse json to object + * + * @param input json string + * @param clazz object type + * @return instance of object + */ + T parseObject(String input, Type clazz); } diff --git a/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/AutowiredProcessor.java b/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/AutowiredProcessor.java index 1fd340b2..e1f12800 100644 --- a/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/AutowiredProcessor.java +++ b/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/AutowiredProcessor.java @@ -174,22 +174,22 @@ private void generateHelper() throws IOException, IllegalAccessException { } } else { // It's normal intent value String originalValue = "substitute." + fieldName; - String statment = "substitute." + fieldName + " = substitute."; + String statement = "substitute." + fieldName + " = substitute."; boolean isActivity = false; if (types.isSubtype(parent.asType(), activityTm)) { // Activity, then use getIntent() isActivity = true; - statment += "getIntent()."; + statement += "getIntent()."; } else if (types.isSubtype(parent.asType(), fragmentTm) || types.isSubtype(parent.asType(), fragmentTmV4)) { // Fragment, then use getArguments() - statment += "getArguments()."; + statement += "getArguments()."; } else { throw new IllegalAccessException("The field [" + fieldName + "] need autowired from intent, its parent must be activity or fragment!"); } - statment = buildStatement(originalValue, statment, typeUtils.typeExchange(element), isActivity); - if (statment.startsWith("serializationService.")) { // Not mortals + statement = buildStatement(originalValue, statement, typeUtils.typeExchange(element), isActivity); + if (statement.startsWith("serializationService.")) { // Not mortals injectMethodBuilder.beginControlFlow("if (null != serializationService)"); injectMethodBuilder.addStatement( - "substitute." + fieldName + " = " + statment, + "substitute." + fieldName + " = " + statement, (StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()), ClassName.get(element.asType()) ); @@ -198,7 +198,7 @@ private void generateHelper() throws IOException, IllegalAccessException { "$T.e(\"" + Consts.TAG + "\", \"You want automatic inject the field '" + fieldName + "' in class '$T' , then you should implement 'SerializationService' to support object auto inject!\")", AndroidLog, ClassName.get(parent)); injectMethodBuilder.endControlFlow(); } else { - injectMethodBuilder.addStatement(statment, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()); + injectMethodBuilder.addStatement(statement, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()); } // Validator @@ -245,7 +245,7 @@ private String buildStatement(String originalValue, String statement, int type, } else if (type == TypeKind.PARCELABLE.ordinal()) { statement += (isActivity ? ("getParcelableExtra($S)") : ("getParcelable($S)")); } else if (type == TypeKind.OBJECT.ordinal()) { - statement = "serializationService.json2Object(substitute." + (isActivity ? "getIntent()." : "getArguments().") + (isActivity ? "getStringExtra($S)" : "getString($S)") + ", $T.class)"; + statement = "serializationService.parseObject(substitute." + (isActivity ? "getIntent()." : "getArguments().") + (isActivity ? "getStringExtra($S)" : "getString($S)") + ", new com.alibaba.android.arouter.facade.model.TypeWrapper<$T>(){}.getType())"; } return statement; @@ -262,7 +262,7 @@ private void categories(Set elements) throws IllegalAccessExc TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); if (element.getModifiers().contains(Modifier.PRIVATE)) { - throw new IllegalAccessException("The autowired fields CAN NOT BE 'private'!!! please check field [" + throw new IllegalAccessException("The inject fields CAN NOT BE 'private'!!! please check field [" + element.getSimpleName() + "] in class [" + enclosingElement.getQualifiedName() + "]"); } diff --git a/gradle.properties b/gradle.properties index 79f8aa25..c2f0526e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,9 +24,9 @@ SUPPORT_LIB_VERSION=25.2.0 MIN_SDK_VERSION=12 TARGET_SDK_VERSION=25 -arouter_compiler_version=1.1.3 -arouter_api_version=1.2.2 -arouter_annotation_version=1.0.3 +arouter_compiler_version=1.1.4 +arouter_api_version=1.2.4 +arouter_annotation_version=1.0.4 bintrayRepo=maven publishedGroupId=com.alibaba