本文主要介绍反射的一些基本概念,基本方法调用,和在java中的一些使用,主要是在模式中的使用如 工程模式,动态代理模式,dagger2,Butterknife 等也会用到
反射的基本概念
获得class<?>的三种方法
Class<?> cls1 = ReflectionActivity.class;
ReflectionActivity activity = new ReflectionActivity();
Class<?> cls2 = activity.getClass();
try {
Class<?> cls3 = Class.forName("com.sun.study.ui.activity.ReflectionActivity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
基本方法罗列
getName():获得类的完整名字。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法。
getModifiers()和Modifier.toString():获得属修饰符,例如private,public,static等
getReturnType():获得方法的返回类型
getParameterTypes():获得方法的参数类型
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法。
getSuperclass():获取某类的父类
getInterfaces():获取某类实现的接口
getAnnotation()获得注解
罗列一个列的所有方法
private void getMethodsInfo() {
Class<ReflectionActivity> cls = ReflectionActivity.class;
Method[] methods = cls.getDeclaredMethods();
if (methods == null) return;
StringBuilder sb = new StringBuilder();
for (Method method:methods) {
sb.append(Modifier.toString(method.getModifiers())).append(" ");
sb.append(method.getReturnType()).append(" ");
sb.append(method.getName()).append("(");
Class[] parameters = method.getParameterTypes();
if (parameters != null) {
for (int i=0; i<parameters.length; i++) {
Class paramCls = parameters[i];
sb.append(paramCls.getSimpleName());
if (i < parameters.length - 1) sb.append(", ");
}
}
sb.append(")\n\n");
}
tvInfo.setText(sb.toString());
}
获得类的属性,并修改器属性的值
private void modifyFieldValue() {
Class<ReflectionActivity> cls = ReflectionActivity.class;
Field[] fields = cls.getDeclaredFields();
if (fields == null) return;
StringBuilder sb = new StringBuilder();
sb.append("获得类的所有属性信息:\n\n");
for (Field field:fields) {
sb.append(Modifier.toString(field.getModifiers())).append(" ");
sb.append(field.getType().getSimpleName()).append(" ");
sb.append(field.getName()).append(";");
sb.append("\n\n");
}
try {
sb.append("属性i的默认值:i = ");
Field f = cls.getDeclaredField("i");
sb.append(f.getInt("i")).append("\n\n");
f.set("i", 100);
sb.append("属性i修改后的值:i = ");
sb.append(f.getInt("i")).append("\n\n");
} catch (Exception e) {
e.printStackTrace();
}
tvInfo.setText(sb.toString());
toolbar.setSubtitle("修改类型Int属性i的值");
}
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK 1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
自定义一个clinckEvent
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface clinckEvent
{
Class<?> listener();
String listenerMethod();
String methodName();
}
再接着定义一个
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@clinckEvent(listener = View.OnClickListener.class, listenerMethodr = "setOnClickListener", methodName = "onClick")
public @interface OnClick
{
int[] value();
}
代码中使用
class Activity{
@OnClick({ R.id.id_btn, R.id.id_btn02 })
public void clickBtnInvoked(View view)
}
通过反射获得注解
Class<? extends Activity> clazz = activity.getClass();
Method[] methods = clazz.getMethods();
//遍历所有的方法
for (Method method : methods)
{
Annotation[] annotations = method.getAnnotations();
//拿到方法上的所有的注解
for (Annotation annotation : annotations)
Class<? extends Annotation> annotationType = annotation
.annotationType();
//拿到注解上的注解
clinckEvent getAnnotation = annotationType
.getAnnotation(clinckEvent.class);
if (getAnnotation != null)
{
//取出设置监听器的名称,监听器的类型,调用的方法名
String listenerSetter = getAnnotation
.listenerSetter();
Class<?> listener = getAnnotation.listener();
String methodName = getAnnotation.methodName();
}
//拿到Onclick注解中的value方法
Method aMethod = annotationType
.getDeclaredMethod("value");
//取出所有的viewId
int[] viewIds = (int[]) aMethod
.invoke(annotation, null);
}
/**
* 注入主布局文件
*
* @param activity
*/
private static void injectContentView(Activity activity)
{
Class<? extends Activity> clazz = activity.getClass();
// 查询类上是否存在ContentView注解
ContentView contentView = clazz.getAnnotation(ContentView.class);
if (contentView != null)// 存在
{
int contentViewLayoutId = contentView.value();
try
{
Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,
int.class);
method.setAccessible(true);
method.invoke(activity, contentViewLayoutId);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
1**工程模式中使用**
public class ProductFatory<T> {
public <T> T Object getInstance(String className){
Object instance=null;
try {
Class cls=Class.forName(className);
instance= cls.newInstance();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return instance;
}
- 代理模式中使用
动态代理
InvocationHandler
Proxy
public interface Subject
{
public void doSomething();
}
public interface Advice
{
public void exe();
}
public class RealAdvice implements Advice
{
public void exe()
{
//验证条件是否满足
}
}
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
public class ProxyHandler implements InvocationHandler
{
private Object proxied;
public ProxyHandler( Object proxied )
{
this.proxied = proxied;
}
public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
{
//在转调具体目标对象之前,可以执行一些功能处理
Boolean isFlag=“增加自己的判断逻辑”
if(isFlag){
new RealAdvice().exe();
}
//转调具体目标对象的方法
return method.invoke( proxied, args);
//在转调具体目标对象之后,可以执行一些功能处理
}
}
client 代码
public class Client
{
public static void main( String args[] )
{
RealSubject real = new RealSubject();
Subject proxySubject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(),
new Class[]{Subject.class},
new ProxyHandler(real));
proxySubject.doSomething();
}
安卓中的BIndler 原理Aidl 通信
一个不错的框架
https://github.com/chenenyu/Router
各业务模块之间不允许存在相互依赖关系,它们之间的跳转通讯采用路由框架 Router 来实现
Router.build(uri).callback(new RouteCallback() { // 添加结果回调
@Override
public void callback(RouteResult state, Uri uri, String message) {
if (state == RouteResult.SUCCEED) {
Toast.makeText(MainActivity.this, "succeed: " + uri.toString(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "error: " + uri + ", " + message, Toast.LENGTH_SHORT).show();
}
}
}).go(this);
增加了注入模块
结合这边文章看
会有意想不到的收获
Activity注入控件view 和点击事件
http://blog.youkuaiyun.com/lmj623565791/article/details/39269193
4. dagger2
module inject component
推荐一篇不错的入门文章
http://www.open-open.com/lib/view/open1482201981550.html
源码学习
/**
* 我们自己的类
*/
@Module
public class MarkCarModule {
public MarkCarModule(){ }
@Provides Engine provideEngine(){
return new Engine("gear");
}
}
/**
* Dagger2生成的工厂类
*/
public final class MarkCarModule_ProvideEngineFactory implements Factory<Engine> {
private final MarkCarModule module;
public MarkCarModule_ProvideEngineFactory(MarkCarModule module) {
assert module != null;
this.module = module;
}
@Override
public Engine get() {
return Preconditions.checkNotNull(
module.provideEngine(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<Engine> create(MarkCarModule module) {
return new MarkCarModule_ProvideEngineFactory(module);
}
/** Proxies {@link MarkCarModule#provideEngine()}. */
public static Engine proxyProvideEngine(MarkCarModule instance) {
return instance.provideEngine();
}
}
/**
* 我们自己的类
*/
@Component(modules = {MarkCarModule.class})
public interface CarComponent {
void inject(Car car);
}
用到了建造者模式
/**
* Dagger2生成的CarComponent实现类
*/
public final class DaggerCarComponent implements CarComponent {
private Provider<Engine> provideEngineProvider;
private MembersInjector<Car> carMembersInjector;
private DaggerCarComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static CarComponent create() {
return builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideEngineProvider = MarkCarModule_ProvideEngineFactory.create(builder.markCarModule);
this.carMembersInjector = Car_MembersInjector.create(provideEngineProvider);
}
@Override
public void inject(Car car) {
carMembersInjector.injectMembers(car);
}
public static final class Builder {
private MarkCarModule markCarModule;
private Builder() {}
public CarComponent build() {
if (markCarModule == null) {
this.markCarModule = new MarkCarModule();
}
return new DaggerCarComponent(this);
}
public Builder markCarModule(MarkCarModule markCarModule) {
this.markCarModule = Preconditions.checkNotNull(markCarModule);
return this;
}
}
}
ublic final class Car_MembersInjector implements MembersInjector<Car> {
private final Provider<Engine> engineProvider;
public Car_MembersInjector(Provider<Engine> engineProvider) {
assert engineProvider != null;
this.engineProvider = engineProvider;
}
public static MembersInjector<Car> create(Provider<Engine> engineProvider) {
return new Car_MembersInjector(engineProvider);
}
@Override
public void injectMembers(Car instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.engine = engineProvider.get();
}
public static void injectEngine(Car instance, Provider<Engine> engineProvider) {
instance.engine = engineProvider.get();
}
}