android IOC框架解析(上)

做android有时候很痛苦的是一件还没技术含量的活但又必须不得不干,比如:

 setContentView(R.layout.activity_main);
 btn_select_all = (Button) findViewById(R.id.btn_select_all);
像这种findViewById每个activity必写,而又对技术提高没任何好处,于是后来进化了一点,变成了这样:
 private <T extends View> T $(int viewId) {
        return (T) findViewById(viewId);
    }
这一般放在BaseActivity上,但是这样也挺麻烦的,就像科技的发展是让人越来越省事,越来越方面,框架的出现也是让你开发更加专注你的业务,
针对上面的问题,IOC就能解决,那么什么是IOC呢?

IOC概念:

让调用类对某一接口实现类的依赖关系由第三方(容器类和协作类)注入
不管是setContentView()和findViewById()都是Activity中的方法,如果我写一个工具类把这个Activity传递进去,这些findViewById()方法放在这个工具类上,这样Activity中就不用findViewById()了,但是xml中的id怎么办呢?所以这个就行不通啊,既然这样的话,能不能通过反射这个Activity然后获取所有的变量,那么这个id怎么传递进去呢?突然想到了,用注解啊,我们只要把这个id写在View上面的注解上不就ok么?所以IOC框架用到的主要技术就是反射和注解.其实很简单,可能听到框架二个词,让你懵逼,没那必要.

今天就讲下setContentView()和findViewById()方法怎么通过IOC框架实现:

ContentViewJect.java(注解)

package com.ioc.annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ContentViewJect {
    int value();
}
ViewJect.java(View的注解)
package com.ioc.annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewInject {
    int value();
}
InjectUtils.java
package com.ioc;
import android.content.Context;
import android.view.View;
import com.ioc.annotion.ContentViewJect;
import com.ioc.annotion.ViewInject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * ioc容器框架
 */
public class InjectUtils {
    public static final String TAG = "InjectUtils";

    public  static  void inject(Context context)
    {
        injectLayout(context);
        injectView(context);
    }
    /**
     * Activity中的findViewById()方法
     * @param context
     */
    public static void injectView(Context context)
    {
        if(context!=null){
            Class<?> clazz=context.getClass();
            Field[] fields=clazz.getDeclaredFields();
            for (Field field:fields)
            {
                ViewInject viewInject=field.getAnnotation(ViewInject.class);
                if(viewInject!=null)
                {
                    int valueId=viewInject.value();//获取view的id
                    try {
                        Method method=clazz.getMethod("findViewById",int.class);
                        View view= (View) method.invoke(context,valueId);
                        field.setAccessible(true);
                        field.set(context,view);//field 表示tv
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /**
     * Activity中的setContentView()方法
     * @param context
     */
    public static void injectLayout(Context context)
    {
        if(context!=null){
            int layoutId=0;
            Class<?> clazz=context.getClass();
            ContentViewJect contentView=clazz.getAnnotation(ContentViewJect.class);
            if (contentView != null ) {
                layoutId=contentView.value();
                try {
                    Method method=clazz.getMethod("setContentView",int.class);
                    method.invoke(context,layoutId);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
这个一般都是写在一个BaseActivity的onCreate()方法中把ioc初始哈

BaseActivity.java

package com.ioc;
import android.app.Activity;
import android.os.Bundle;
public class BaseActivity  extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectUtils.inject(this);
    }
}
MainActivity.java
package com.ioc;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import com.ioc.annotion.ContentViewJect;
import com.ioc.annotion.ViewInject;
@ContentViewJect(R.layout.activity_main)
public class MainActivity extends BaseActivity{
    public static  final String TAG="dongnao";
    @ViewInject(R.id.text)
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv.setText("zhouguizhi_ioc");
    }
}

如图所示:


IOC缺点的话,用到反射会影响点性能!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值