From 071b48d4ce84e6d6612e6d4d48b269ff6463f8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A3=E7=BA=AC?= Date: Tue, 28 Feb 2017 18:49:12 +0800 Subject: [PATCH] Fix autowired performance issues and use alias name replace field name when inject. --- .../android/arouter/demo/MainActivity.java | 4 +- arouter-api/build.gradle | 2 +- .../arouter/core/AutowiredServiceImpl.java | 52 +++++++++++++++++++ .../android/arouter/core/LogisticsCenter.java | 22 ++++---- .../facade/service/AutowiredService.java | 19 +++++++ .../android/arouter/launcher/_ARouter.java | 17 +++--- arouter-compiler/build.gradle | 2 +- .../processor/AutowiredProcessor.java | 3 +- .../compiler/processor/RouteProcessor.java | 2 +- 9 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 arouter-api/src/main/java/com/alibaba/android/arouter/core/AutowiredServiceImpl.java create mode 100644 arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/AutowiredService.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 da51a9aa..70895031 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 @@ -1,8 +1,6 @@ package com.alibaba.android.arouter.demo; import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; @@ -79,7 +77,7 @@ public void onClick(View v) { ARouter.getInstance().build("/test/activity1") .withString("name", "老王") .withInt("age", 18) - .withBoolean("girl", true) + .withBoolean("boy", true) .withLong("high", 180) .withString("url", "https://a.b.c") .navigation(); diff --git a/arouter-api/build.gradle b/arouter-api/build.gradle index fb15dac6..38ffd0fd 100644 --- a/arouter-api/build.gradle +++ b/arouter-api/build.gradle @@ -5,7 +5,7 @@ ext { artifact = bintrayName libraryName = 'ARouter sdk' libraryDescription = 'A router for android' - libraryVersion = '1.0.6' + libraryVersion = '1.0.7' } android { diff --git a/arouter-api/src/main/java/com/alibaba/android/arouter/core/AutowiredServiceImpl.java b/arouter-api/src/main/java/com/alibaba/android/arouter/core/AutowiredServiceImpl.java new file mode 100644 index 00000000..b9e53ad7 --- /dev/null +++ b/arouter-api/src/main/java/com/alibaba/android/arouter/core/AutowiredServiceImpl.java @@ -0,0 +1,52 @@ +package com.alibaba.android.arouter.core; + +import android.content.Context; + +import com.alibaba.android.arouter.facade.annotation.Route; +import com.alibaba.android.arouter.facade.service.AutowiredService; +import com.alibaba.android.arouter.facade.template.ISyringe; + +import org.apache.commons.collections4.map.LRUMap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.alibaba.android.arouter.utils.Consts.SUFFIX_AUTOWIRED; + +/** + * Autowired service impl. + * + * @author zhilong Contact me. + * @version 1.0 + * @since 2017/2/28 下午6:08 + */ +@Route(path = "/arouter/service/autowired") +public class AutowiredServiceImpl implements AutowiredService { + private Map classCache; + private List blackList; + + @Override + public void init(Context context) { + classCache = new LRUMap<>(); + blackList = new ArrayList<>(); + } + + @Override + public void autowire(Object instance) { + String className = instance.getClass().getName(); + try { + if (!blackList.contains(className)) { + ISyringe autowiredHelper = classCache.get(className); + if (null == autowiredHelper) { // No cache. + autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance(); + } + autowiredHelper.inject(instance); + classCache.put(className, autowiredHelper); + } + } catch (Exception ex) { + // ARouter.logger.error(TAG, "Autowired made exception, in class [" + className + "]"); + blackList.add(className); // This instance need not autowired. + } + } +} diff --git a/arouter-api/src/main/java/com/alibaba/android/arouter/core/LogisticsCenter.java b/arouter-api/src/main/java/com/alibaba/android/arouter/core/LogisticsCenter.java index d6aa76d0..4c2d1036 100644 --- a/arouter-api/src/main/java/com/alibaba/android/arouter/core/LogisticsCenter.java +++ b/arouter-api/src/main/java/com/alibaba/android/arouter/core/LogisticsCenter.java @@ -154,7 +154,7 @@ public synchronized static void completion(Postcard postcard) { setValue(postcard, params.getValue(), params.getKey(), - resultMap.get(TextUtils.getRight(params.getKey()))); + resultMap.get(params.getKey())); } // Save params name which need autoinject. @@ -200,37 +200,35 @@ public synchronized static void completion(Postcard postcard) { */ private static void setValue(Postcard postcard, Integer typeDef, String key, String value) { try { - String currentKey = TextUtils.getLeft(key); - if (null != typeDef) { switch (typeDef) { case Consts.DEF_BOOLEAN: - postcard.withBoolean(currentKey, Boolean.parseBoolean(value)); + postcard.withBoolean(key, Boolean.parseBoolean(value)); break; case Consts.DEF_BYTE: - postcard.withByte(currentKey, Byte.valueOf(value)); + postcard.withByte(key, Byte.valueOf(value)); break; case Consts.DEF_SHORT: - postcard.withShort(currentKey, Short.valueOf(value)); + postcard.withShort(key, Short.valueOf(value)); break; case Consts.DEF_INT: - postcard.withInt(currentKey, Integer.valueOf(value)); + postcard.withInt(key, Integer.valueOf(value)); break; case Consts.DEF_LONG: - postcard.withLong(currentKey, Long.valueOf(value)); + postcard.withLong(key, Long.valueOf(value)); break; case Consts.DEF_FLOAT: - postcard.withFloat(currentKey, Float.valueOf(value)); + postcard.withFloat(key, Float.valueOf(value)); break; case Consts.DEF_DOUBLE: - postcard.withDouble(currentKey, Double.valueOf(value)); + postcard.withDouble(key, Double.valueOf(value)); break; case Consts.DEF_STRING: default: - postcard.withString(currentKey, value); + postcard.withString(key, value); } } else { - postcard.withString(currentKey, value); + postcard.withString(key, value); } } catch (Throwable ex) { logger.warning(Consts.TAG, "LogisticsCenter setValue failed! " + ex.getMessage()); diff --git a/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/AutowiredService.java b/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/AutowiredService.java new file mode 100644 index 00000000..fcb8e4af --- /dev/null +++ b/arouter-api/src/main/java/com/alibaba/android/arouter/facade/service/AutowiredService.java @@ -0,0 +1,19 @@ +package com.alibaba.android.arouter.facade.service; + +import com.alibaba.android.arouter.facade.template.IProvider; + +/** + * Service for autowired. + * + * @author zhilong Contact me. + * @version 1.0 + * @since 2017/2/28 下午6:06 + */ +public interface AutowiredService extends IProvider { + + /** + * Autowired core. + * @param instance the instance who need autowired. + */ + void autowire(Object instance); +} diff --git a/arouter-api/src/main/java/com/alibaba/android/arouter/launcher/_ARouter.java b/arouter-api/src/main/java/com/alibaba/android/arouter/launcher/_ARouter.java index b41024c0..c1587582 100644 --- a/arouter-api/src/main/java/com/alibaba/android/arouter/launcher/_ARouter.java +++ b/arouter-api/src/main/java/com/alibaba/android/arouter/launcher/_ARouter.java @@ -16,11 +16,11 @@ import com.alibaba.android.arouter.facade.Postcard; import com.alibaba.android.arouter.facade.callback.InterceptorCallback; import com.alibaba.android.arouter.facade.callback.NavigationCallback; +import com.alibaba.android.arouter.facade.service.AutowiredService; import com.alibaba.android.arouter.facade.service.DegradeService; import com.alibaba.android.arouter.facade.service.InterceptorService; import com.alibaba.android.arouter.facade.service.PathReplaceService; import com.alibaba.android.arouter.facade.template.ILogger; -import com.alibaba.android.arouter.facade.template.ISyringe; import com.alibaba.android.arouter.thread.DefaultPoolExecutor; import com.alibaba.android.arouter.utils.Consts; import com.alibaba.android.arouter.utils.DefaultLogger; @@ -31,9 +31,6 @@ import java.lang.reflect.Method; import java.util.concurrent.ThreadPoolExecutor; -import static com.alibaba.android.arouter.utils.Consts.SUFFIX_AUTOWIRED; -import static com.alibaba.android.arouter.utils.Consts.TAG; - /** * ARouter core * @@ -169,12 +166,9 @@ static void setLogger(ILogger userLogger) { } static void inject(Object thiz) { - try { - Class autowiredClass = Class.forName(thiz.getClass().getName() + SUFFIX_AUTOWIRED); - ISyringe iSyringe = (ISyringe) autowiredClass.getConstructor().newInstance(); - iSyringe.inject(thiz); - } catch (Exception ex) { - logger.error(TAG, "Autowired made exception, message [" + ex.getMessage() + "]"); + AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation()); + if (null != autowiredService) { + autowiredService.autowire(thiz); } } @@ -245,7 +239,8 @@ private String extractGroup(String path) { } static void afterInit() { - interceptorService = ARouter.getInstance().navigation(InterceptorService.class); // Trigger interceptor init. + // Trigger interceptor init, use byName. + interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation(); } protected T navigation(Class service) { diff --git a/arouter-compiler/build.gradle b/arouter-compiler/build.gradle index 3352922a..b1db8d15 100644 --- a/arouter-compiler/build.gradle +++ b/arouter-compiler/build.gradle @@ -5,7 +5,7 @@ ext { artifact = bintrayName libraryName = 'ARouter compiler' libraryDescription = 'A compiler for ARouter to find route' - libraryVersion = '1.0.2' + libraryVersion = '1.0.3' } compileJava { 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 f73bbadc..674b8dc6 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 @@ -14,6 +14,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.util.ArrayList; @@ -167,7 +168,7 @@ private void generateHelper() throws IOException, IllegalAccessException { } statment = buildStatement(statment, TypeUtils.typeExchange(element.asType()), isActivity); - injectMethodBuilder.addStatement(statment, fieldName); + injectMethodBuilder.addStatement(statment, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()); // Validater if (fieldConfig.required() && !element.asType().getKind().isPrimitive()) { // Primitive wont be check. diff --git a/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/RouteProcessor.java b/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/RouteProcessor.java index bf6e2403..f7e3c6b8 100644 --- a/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/RouteProcessor.java +++ b/arouter-compiler/src/main/java/com/alibaba/android/arouter/compiler/processor/RouteProcessor.java @@ -222,7 +222,7 @@ private void parseRoutes(Set routeElements) throws IOExceptio if (field.getKind().isField() && field.getAnnotation(Autowired.class) != null && !typeUtil.isSubtype(field.asType(), iProvider)) { // It must be field, then it has annotation, but it not be provider. Autowired paramConfig = field.getAnnotation(Autowired.class); - paramsType.put(StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : field.getSimpleName().toString() + "|" + paramConfig.name(), TypeUtils.typeExchange(field.asType())); + paramsType.put(StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : paramConfig.name(), TypeUtils.typeExchange(field.asType())); } } routeMete = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType);