标签:
先不说话
Class LogHandler |
执行统一操作 |
|
获取方法注解,获取参数注解 |
|
获取参数的值 |
Interface LogUtil |
定义方法,做方法注解,做参数注解 |
|
|
|
|
Parms |
参数注解 |
|
|
|
|
Method |
方法注解 |
|
|
|
|
1.Params 注解
package com.sclgxt.invokeapplication; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Sclgxton 2016/5/5. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Params { String value() default ""; }2.Method注解
package com.sclgxt.invokeapplication; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Sclgxt on 2016/5/5. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Tag { String value() default ""; }
3.CallBack
4.LogUtilpackage com.sclgxt.invokeapplication; /** * Created by Sclgxt on 2016/5/5. */ public interface CallBack { void log(String message); }
package com.sclgxt.invokeapplication; /** * Created by Sclgxt on 2016/5/5. */ public interface LogUtil { @Tag("男神") void print(@Params("Name") String message, CallBack callBack); @Tag("女神") void print(@Params("Name") String name, @Params("Age") String age, CallBack callBack); }5.LogHandler
package com.sclgxt.invokeapplication; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; /** * Created by Dell on 2016/5/5. */ public class LogHandler<T> { private static LogHandler logPrint; private static Map<String, Object> map = new HashMap<>(); private LogHandler() { } public static LogHandler getInstance() { if (logPrint == null) { logPrint = new LogHandler(); } return logPrint; } public LogUtil create(Class mclass) { /** * 缓存中去 */ Object o = null; map.get(mclass); /** * 取不到则取构造代理对象 */ if (o == null) { o = Proxy.newProxyInstance(LogHandler.class.getClassLoader(), new Class[]{mclass}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final CallBack callback = (CallBack) args[args.length - 1]; final Tag tag = method.getAnnotation(Tag.class); if (tag != null) { /** * 获得方法注解的值 */ StringBuilder tagvalue = new StringBuilder(); tagvalue.append(tag.value()); tagvalue.append("\n"); System.out.println(tagvalue.toString()); /** * 获得所有参数上的注解 */ Annotation[][] methodParameterAnnotationArrays = method.getParameterAnnotations(); if (methodParameterAnnotationArrays != null) { int count = methodParameterAnnotationArrays.length; for (int i = 0; i < count; i++) { /** * 获得单个参数上的注解 */ Annotation[] methodParameterAnnotations = methodParameterAnnotationArrays[i]; if (methodParameterAnnotations != null) { for (Annotation methodParameterAnnotation : methodParameterAnnotations) { /** * 如果是Params注解 */ if (methodParameterAnnotation instanceof Params) { /** * 取得Params注解上的值 */ Params paramsinterface = (Params) methodParameterAnnotation; String paramsvalue = paramsinterface.value(); System.out.println(paramsvalue); /** * 这是对应的参数的值 */ tagvalue.append(paramsvalue + ": "); System.out.println(args[i]); tagvalue.append(args[i]); tagvalue.append("\n"); /** * 使用Params注解替换get注解中的值为参数值 */ } } } } } callback.log(tagvalue.toString()); } return null; } }); map.put(mclass.toString(), o); } return (LogUtil) o; } }6.使用
final TextView tv = (TextView) findViewById(R.id.view); LogUtil logUtil = LogHandler.getInstance().create(LogUtil.class); logUtil.print("林允儿", "22", new CallBack() { @Override public void log(String message) { tv.setText(message); Log.i("", "-->" + message); } }); logUtil.print("郭碧婷", new CallBack() { @Override public void log(String message) { tv.setText(tv.getText() + "\n" + message); Log.i("", "-->" + message); } });7.效果
8.为什么这么写,为了那些虽然参数不同,方法名也不尽相同,但是它们都执行统一的操作的方法,我感觉这就是为了装逼,因为我们总有其他方法来实现;
第一次看见的时候,是在一个同事写的网络请求之中:给你们贴一段代码
NetUtil
//请求验证码 @POST("/api/common/queryCode") NetRequest getCode(@PARAMS("mobile") String mobile, @PARAMS("type") int type); //请求用户信息 @POST("/api/user/queryInfo") NetRequest<UserInfo> queryInfo(@PARAMS("sign") String sign); //登录 @POST("/api/user/login") NetRequest<User> login( @PARAMS("code") String code, @PARAMS("network") int network, @PARAMS("brand") String brand, @PARAMS("lat") double lat, @PARAMS("lng") double lng, @PARAMS("brandId") String brandId, @PARAMS("ostype") int ostype, @PARAMS("osversion") String osversion, @PARAMS("maptype") String maptype, @PARAMS("countryCode") String countryCode, @PARAMS("register_channel") String register_channel );
就这样,通过和后台商量好数据返回格式,再知道返回数据类型,就可以轻易的得到自己想要的各种class 数据,当然我们还有其他的实现方式,总之我还是觉得这是装逼!!!!!!!之前1-6的代码,拷贝下来可以运行,原理就不说了,自己想去!!Proxy.newProxyInstance()这个方法的第一个参数,ClassLoder 没什么作用....
标签:
原文地址:http://blog.csdn.net/sclgxt/article/details/51329415