zoukankan      html  css  js  c++  java
  • java 中的 viewUtils框架

    IoC的概念介绍

    控制反转(IOC)模式(又称DI:Dependency Injection)就是Inversion of Control,控制反转。在Java开发中,IoC意 味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。

    控制反转(Inversion of Control,英文缩写为IoC)是框架的重要特征,做到控制反转需要一个容器来实现,就是我们所说的IoC容器,最常见的IoC容器是Spring。

    控制反转从字面意思看来不是很好理解,其实就是将创建管理对象的工作交给容器来做。在以前的编程中,创建一个对象需要显式的new出来,但是控制反转是在容器初始化(或者某个指定时间节点)时通过反射机制(上一篇文章有介绍)创建好对象,在使用时去容器中获取。将对象的控制权反过来交给容器管理,所以称之为“控制反转”。

    ViewUtils视图相关工具类

    功能:

    • android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;
    • 新的事件绑定方式,使用混淆工具混淆后仍可正常工作;
    • 目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event

    我们使用ViewUtils框架来实现android中的findViewbyId和setOnClickListener的点击事件

    首先下载viewUtils的jar包

    添加到项目中

    我们来看看utils的一个简单的使用

    package im.weiyuan.com.viewutils;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.lidroid.xutils.ViewUtils;
    import com.lidroid.xutils.view.annotation.ViewInject;
    import com.lidroid.xutils.view.annotation.event.OnClick;
    
    public class MainActivity extends AppCompatActivity {
        @ViewInject(R.id.tv_main_title)
        private TextView tv_main_title;
        @ViewInject(R.id.btn_main)
        private Button btn_main;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //这里一定要初始化注解
            ViewUtils.inject(this);
        }
    
        @OnClick(R.id.btn_main)
        //login的参数必须是 View view
        public  void login(View view ){
            Toast.makeText(MainActivity.this,"事件被点击了",Toast.LENGTH_LONG).show();
       }
    }
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="im.weiyuan.com.viewutils.MainActivity">
    
        <TextView
            android:id="@+id/tv_main_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!" />
    
        <Button
            android:text="点击"
            android:id="@+id/btn_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

     接下来我们我们编译一个自定义的注解类

     在eliclipse中新建一个注解类:

    public @interface ViewInject {
    
    }

     注解类是以

     @interface开头的
    @Target 是Java的元注解(指修饰注解的注解)之一。用来指定注解修饰类的哪个成员。
    加大括号表示一个数组,指被修饰的注解能用于多个不同的类成员。
    举个栗子:
    @Target(ElementType.FIELD)
    public @interface A{}

    表示注解A只能用来修饰类中的Field
    @Target({ElementType.FIELD, ElementType.METHOD})
    public @interface A{}

    表示注解A能用来修饰类中的Field和Method
    用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,在运行的时候不被虚拟机保留;
    用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息不会留在class文件中,注解的信息只会留在源文件中;
    用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,

    5  为注解增加各种属性

    什么是注解的属性?
          一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是黑马的学生,否则,就不是。

          如果还想区分出是黑马哪个班的学生,这时候可以为胸牌再增加一个属性来进行区分。

          加了属性的注解效果为:@MyAnnotation(color="red")。

    定义基本类型的属性和应用属性:
          在注解类中增加String color(); 被添加的注解设置属性值:@MyAnnotation(color="red")。

    我们来看下程序的代码:

    package www.weiyuan.test;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.lang.model.element.Element;
    
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ViewInject {
    
        int age();
        String name();
    }

    我们定义了一个注解类ViewInject ,该类运行的声明周期是真个程序运行的声明周期

    对普通成员类的字段进行注解

    现在我们定义了一个普通的user类

    package www.weiyuan.test;
    
    
    public class User {
      @ViewInject(age =10, name = "45554")
      private String name;
      private int age;
      private void  eat(String eat){
          
      }
    }

    上面就是一个简单的用法

    如果注解类中不指明是对成员变量进行注解,写成下面的形式

    package www.weiyuan.test;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.lang.model.element.Element;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ViewInject {
    
        int age();
        String name();
    }

    默认表示可以对普通类的整个类进行注解,可以是类的成员变量,也可以注解类的函数方法

    本质上注解就是标签:上面就是对user类贴上了一个标签

    在详细介绍注解之前先分析下反射的原理

    我们来详细的看下面的一个列子相当的经典:

    package www.weiyuan.test;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.lang.model.element.Element;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ViewInject {
    
        int age();
        String name();
    }
    package www.weiyuan.test;
    
    
    public class User {
        //添加在属性name上面的注解
      @ViewInject(age =10, name = "45554")
      private String name;
      private int age;
      private void  eat(String eat){
          System.out.println(eat);
      }
    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }
    }

    主程序:

    package www.weiyuan.test;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    
    
    public class Test {
        
        public static void main(String[] args) {
            
            User user = new User();
            //首先获得对象的字节码文件
            Class classz = User.class;
            //对该文件进行破解 getDeclaredField不管是私有变量还是公开变量都能够获得
            try {
                Field field = classz.getDeclaredField("name");
                Field field2 = classz.getDeclaredField("age");
                //获得该字段上面的注解类
                ViewInject annotation = field.getAnnotation(ViewInject.class);
                if(annotation != null){
                    //获得自定义注解类中的参数
                    int age = annotation.age();
                    String name = annotation.name();
                    
                    //通过暴力反射,将获得的值赋值给user对象
                    //设置字段的可以暴力反射
                    field.setAccessible(true);
                    field2.setAccessible(true);
                    //给上面创建的值设置name属性的值
                    field.set(user, name);
                    field2.set(user, age);
                    System.out.println(user.toString());
                    //打印输出是:User [name=45554, age=10]
                }
                
                //调用User类的eat方法
                Method declaredMethod = classz.getDeclaredMethod("eat",String.class);
                //让该方法可以执行
                declaredMethod.setAccessible(true);
                
                declaredMethod.invoke(user, "吃饭了");
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            }
        
    
        
      
           
       
    }

    程序的运行结果是:

  • 相关阅读:
    【3.1】学习C++之再逢const
    【8】学习C++之this指针
    【7】学习C++之类的构造函数
    【6】学习C++之类的实例化及访问
    【5】学习C++之类的概念
    【4】学习C++之内存管理
    【3】学习C++之const关键字的使用
    【2】学习C++之引用
    【C#第一天】数据相关
    【1】学习C++时,一些零散知识点01
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7213979.html
Copyright © 2011-2022 走看看