1. 程式人生 > 實用技巧 >阻止事件冒泡的兩種方式

阻止事件冒泡的兩種方式

前言

  部落格正在整理中

使用場景

靜態代理

介面

public interface IInfoService {
    void setInfo();
}

操作

public class InfoDao implements IInfoService {

    @Override
    public void setInfo() {
        Log.e("除錯_臨時_log", "設定資料中");
    }
}

代理

public class InfoDaoProxy implements IInfoService {
    private IInfoService iInfoService;

    
public InfoDaoProxy(IInfoService service){ this.iInfoService = service; } @Override public void setInfo() { Log.e("除錯_臨時_log", "this_馬上設定"); iInfoService.setInfo(); Log.e("除錯_臨時_log", "this_設定完成"); } }

結果:

動態代理

動態代理有以下特點:
1.代理物件,不需要實現介面
2.代理物件的生成,是利用JDK的API,動態的在記憶體中構建代理物件(需要我們指定建立代理物件/目標物件實現的介面的型別)
3.動態代理也叫做:JDK代理,介面代理

JDK中生成代理物件的API
代理類所在包:java.lang.reflect.Proxy
JDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個引數,完整的寫法是:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

注意該方法是在Proxy類中是靜態方法,且接收的三個引數依次為:

  • ClassLoader loader,:指定當前目標物件使用類載入器,獲取載入器的方法是固定的
  • Class<?>[] interfaces,
    :目標物件實現的介面的型別,使用泛型方式確認型別
  • InvocationHandler h:事件處理,執行目標物件的方法時,會觸發事件處理器的方法,會把當前執行目標物件的方法作為引數傳入

註解

@Documented
@Target(METHOD)
@Retention(RUNTIME)
@interface Info {
    String name() default "";
    int id() default 0;
}

介面

public interface IInfoService {
    @Info(name = "小明", id = 1)
    Call setInfo(Boolean sex);
}

返回操作類

public class Call {
    private List<Object> valueList;

    protected Call(List<Object> list) {
        valueList = list;
    }

    public String execute(){
        if (valueList == null || valueList.size() == 0){
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (Object o : valueList){
            if (o instanceof String){
                stringBuilder.append(o);

            }else if (o instanceof Integer){
                stringBuilder.append(o);

            }else if (o instanceof Long){
                stringBuilder.append(o);

            }else if (o instanceof Boolean){
                stringBuilder.append(o);

            }else if (o instanceof Float){
                stringBuilder.append(o);

            }else if (o instanceof Double){
                stringBuilder.append(o);

            }
        }
        return stringBuilder.toString();
    }
}

代理

public class InfoDaoProxy {


    public static <T> T create(Class<T> service){
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getDeclaringClass() == Object.class) {
                    return method.invoke(this, args);
                }
                List<Object> objects = new ArrayList<>();
                Info info = method.getAnnotation(Info.class);
                objects.add(info.name());
                objects.add(info.id());
                if (args != null){
                    for (Object o : args){
                        objects.add(o);
                    }

                }
                return new Call(objects);
            }
        });
    }
}

End