Android 之动态代理
来源:互联网 发布:类似江南布衣淘宝店 编辑:程序博客网 时间:2024/06/08 08:21
先不说话
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 没什么作用....
0 0
- Android 之动态代理
- Android 插件之Hook机制动态代理
- Android10--Android之动态代理详解
- Android动态加载之代理Activity模式
- 代理模式之动态代理
- 代理模式之动态代理
- 代理模式之动态代理
- 代理模式之动态代理
- AOP代理之动态代理
- AOP代理之动态代理
- Java 代理之 动态代理
- 代理模式之动态代理
- 代理模式之动态代理
- 代理模式之动态代理
- 代理模式之动态代理
- 动态代理之cglib代理
- 代理模式之动态代理
- 代理模式之动态代理
- Java 多线程
- 设计模式C++学习笔记之二(Proxy代理模式)
- Android 用户定位
- HTML5——本地资源拖放
- 图文混排
- Android 之动态代理
- 链接时候提示undefined reference
- 设计模式C++学习笔记之三(Singleton单例模式)
- C++作业5
- Python 主要模块和常用方法简览
- C++作业4
- 基于接口开发的令牌
- CSS基础(七):z-index详解
- 学习Android Studio开发工具之Activity3(框架3)