首页 > 其他分享 >有了它,再也不用写setContentView了!好用,真的好用~

有了它,再也不用写setContentView了!好用,真的好用~

时间:2023-06-21 14:00:48浏览次数:53  
标签:setContentView class public MainActivity 获取 注解 再也 ElementType 好用


前言

大家多多少少都用过或者看过注解(Annotation),比如最常见@Override、@Deprecated等。近年来一些比较流行的三方框架都使用的注解,像ButterKnife(渐渐被Databinding、ViewBinding取代,已经停止维护)、Dagger、Room等等。那为什么这些大牛都这么热衷于使用注解呢?原因肯定是注解的好处多多了。

有了它,再也不用写setContentView了!好用,真的好用~_Test

作者

猪猪侠aoa

注解的优点

  • 代码的检查,将一些错误暴露在运行期之前。
  • 减少重复的工作,提高工作效率。例如ButterKnife,可以减少我们的findViewById,设置点击事件等。
  • 降低代码的耦合。典型的就是Dagger。
  • 信息配置,运行时利用反射动态处理。

元注解(meta-annotation)

什么叫元注解,意思就是在JDK中定义好的注解。在JDK1.5中提供了4个元注解

@Target

表示该注解用于哪个位置,例如作用在类、方法等上面,详细的作用范围如下:

  • ElementType.TYPE 类、接口(包括注解类型)或枚举声明
  • ElementType.FIELD 字段声明
  • ElementType.METHOD 方法声明
  • ElementType.PARAMETER 方法的参数声明
  • ElementType.CONSTRUCTOR 类的构造法声明
  • ElementType.LOCAL_VARIABLE 局部变量声明
  • ElementType.ANNOTATION_TYPE 注解声明
  • ElementType.PACKAGE 包声明
  • ElementType.TYPE_PARAMETER JDK1.8新加的,类型参数声明
  • ElementType.TYPE_USE JDK1.8新加的,类型使用声明

@Retention

表示注解的生命周期

  • RetentionPolicy.SOURCE 源码阶段,在编译时会去除
  • RetentionPolicy.CLASS 注解会保存在class文件中,运行时会去除
  • RetentionPolicy.RUNTIME 注解会一直存在,在运行时可以利用反射去获取注解上面对应的值

@Inherited

表示允许子类继承父类的注解类型

@Documented

表示文档注解

今天我们就是利用运行时注解的特性,来做一些骚操作。

自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationTest {
	int value();
}

上面的代码自定义了一个AnnotationTest注解,@Target是ElementType.TYPE,表示是作用在类、接口或者枚举上面的。@Retention是RetentionPolicy.RUNTIME,表示在运行时期。内部定义了一个返回值为int的方法,表示使用注解时要传递一个int型的参数。那下面我们建个类来看看如何使用。

@AnnotationTest(1)
public class Test {
}
Test test = new Test();
//获取Test的Class对象
Class<? extends Test> clazz = test.getClass();
//使用Class对象获取对应的注解
AnnotationTest annotation = clazz.getAnnotation(AnnotationTest.class);
if (annotation != null) {
       //获取注解传递的值
       int value = annotation.value();
       Log.d(TAG, "initView: >>>>>>>>>>>" + value);
}

有了它,再也不用写setContentView了!好用,真的好用~_注解_02

上面代码首先定义了一个Test类,然后使用@AnnotationTest注解,传递数值1.然后使用反射获取该类的注解,接着获取注解传递的值,如上图打印出来的是1。

那下面开始进入我们今天的主题,使用注解去设置Activity的页面布局,不在用setContentView了。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}

定义了一个ContentView注解,返回值是int型的方法。

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectUtils.injectLayout(this);
        initView();
    }

    protected void initView() {

    }
}

非常简单的一个BaseActivity

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {
}

MainActivity,使用ContentView注解,然后注解传递布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

MainActivity的布局

还有一个InjectUtils类,获取MainActivity的注解和布局,然后在设置给MainActivity,主要的操作就是放在InjectUtils类中。

public class InjectUtils {
	public static void injectLayout(Object context) {
    	//获取Class对象,这里context就是传递过来的MainActivity
        Class<?> clazz = context.getClass();
        //获取@ContentView注解
        ContentView contentView = clazz.getAnnotation(ContentView.class);
        if (contentView != null) {
        	//获取注解中的布局文件
            int layoutId = contentView.value();
            try {
            	//利用反射调用Activity中的setContentView方法,将布局设置给MainActivity
                Method setContentViewMethod = clazz.getMethod("setContentView", int.class);
                setContentViewMethod.invoke(context, layoutId);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}

有了它,再也不用写setContentView了!好用,真的好用~_java_03

如上图所以,已经成功的将布局文件设置给了MainActivity。上面的injectLayout方法中主要的操作已经加了注释,这里我就不一一解释了。其实除了使用注解设置Activity的布局,还是使用注解替代fingViewById,设置点击等等。有需要看使用注解去设置控件和点击事件的,可以戳这里

这里我要说的一点就是通过反射获取方法对于有些同学可能会存在的坑(准备的说应该是自己不经常用反射的原因吧),我之前就被这个坑了好久,不过踩过这种坑会让我更加记忆深刻,也让我对反射有了新的认识。

getMethod和getDeclaredMethod的区别

  • getMethod 可以获取自身以及父类的被public修饰的方法
  • getDeclaredMethod 可以获取自身任何的方法,父类的方法是获取不到,哪怕父类的方法是用public修饰的也无法获取。

IOC

IOC,Inversion of Control的缩写,是控制反转。 什么意思呢?IOC是原来由程序代码中主动获取的资源,转变由第三方获取并使原来的代码被动接收的方式,以达到解耦的效果,称为控制反转。最常见的方式就是依赖注入(Dependency Injection),简称DI。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。

我个人的理解,就是把事情交给别人做,做好了之后把成果交给我就行了。 举个简单的例子,老板招了个年轻又漂亮的秘书。老板要和另一家公司合作要吃饭是吧,那秘书负责定酒店,定好之后告诉老板。那合作伙伴喝多了,老板叫秘书定房间,然后秘书定好房间了之后告诉老板。这就是传中的有事秘书干,没事。。。

有了它,再也不用写setContentView了!好用,真的好用~_android_04

依赖注入它是一种思想,没有什么标准。就像面向对象思想一样,说简单也简单。说难它就太难了。能领略到思想真谛了,那绝非一朝一夕的时间能做到的。只有通过我们不断积累,不断的实战才有可能做到。

总结

今天主要说的是注解,然后使用运行时注解去设置Acivity的布局,控件等。后面又简单的谈了一下依赖注入,不是很详细。那今天就到这里,大家加油。

文末

感谢大家关注我,分享Android干货,交流Android技术。
对文章有何见解,或者有何技术问题,都可以在评论区一起留言讨论,我会虔诚为你解答。
Android架构师系统进阶学习路线、58万字学习笔记、教学视频免费分享地址:我的GitHub

有了它,再也不用写setContentView了!好用,真的好用~_注解_05


标签:setContentView,class,public,MainActivity,获取,注解,再也,ElementType,好用
From: https://blog.51cto.com/u_16163510/6528337

相关文章

  • 在 Mac 上用 Windows 系统,如何让你的触控板更好用?
    转自:https://sspai.com/post/56799驱动附件下载地址:https://files.cnblogs.com/files/y593216/Drivers-amd64-ReleaseMSSigned.zip?t=1687275496&download=true  MacBook触控板超大的触控面积、顺滑的滑动体验以及以假乱真的ForceTouch震动一直以来都是其他笔记本难以......
  • 永宏plc和台达vfd-m变頻器modbs rtu通讯程序史上最好用的plc和变頻器rtu通讯程序,甩三
    永宏plc和台达vfd-m变頻器modbsrtu通讯程序史上最好用的plc和变頻器rtu通讯程序,甩三菱bd板通讯几条街了,程序简单易用,好上手功能强大,控制监视效果可以看视频,说走就走。使用的是永宏fbs-20mctplc,A,B,N系列也都支持。内容包含plc和威纶通触摸屏程序,变頻器参数设置和通讯接线,plc程......
  • OPCServer DA OPC服务端opcserver发包)好用,几百个应用现场
    OPCServerDAOPC服务端opcserver发包)好用,几百个应用现场二次开发源代码,C#开发,可二次开发。已应用到多个行业的几百个应用现场,长时间运行稳定,可靠。本项目中提供测试OPCServer的软件开发源码,有详细的注释,并提供详细的使用说明,二次开发清晰明了。文件中提供测试过程视频,操作简单,......
  • photoshop哪个版本最好用?PS电脑版下载安装 软件大全
    Photoshop2023最新版是一款由Adobe公司在2022年10月份推出的最新图像图形处理工具。该软件拥有十分多强大且专业的图像处理功能,可以帮助用户在线打开编辑各种格式的图像。相较于旧版本的PS来说,它新加入了批量图片P图功能,通过最新的AI技术支持可以一键快速P图,并且处理的图片也是相当......
  • 好用网址分享-77ai导航与77搜索导航
    AI(人工智能)技术正在改变我们的生活方式和工作方式,越来越多的人开始关注和使用AI相关的网站和应用程序。在这篇文章中,我将为大家介绍一些常用的AI网址导航,帮助您更好地了解和使用AI技术。AIHubAIHub是由GoogleCloud推出的一个开放平台,旨在帮助企业和开发者快速构建、部署和管......
  • setContentView(R.layout.activity_);ui->setupUi(this);
    publicclassTutorialPartIIIextendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//setContentView(R.layout.activity_tutorial_part_iii);//*......
  • 花了一周时间,总算把mysql的加锁搞清楚了,再也不怕间隙锁和next-key了
    接触mysql都知道在mysql中有很多锁,共享锁(S)、排他锁(X)、间隙锁(gap)、next-key,当然还有意向锁、表锁等。今天不讲别的,专门来看下innodb引擎下的锁是什么样子的。现在有这样一条sql语句,你知道是什么锁吗?updatetsetname='1'whereid=10;可能会说是锁住id=10的行锁吧,没错行锁是一......
  • 降本增效的开源微服务平台好用吗?
    在快节奏的现代社会生活中,办公职场需要实现降本增效的目标,就需要跟随社会发展的脚步“引进来,走出去”。低代码技术平台是当前企业级应用低代码平台,其中,开源微服务平台优势多,更灵活,深得广大用户朋友的信赖。今天,我们就一起来看看开源微服务平台的优势特点。1、低代码技术的应用价......
  • 如何选择一款好用的工单系统?
    随着市面上的工单管理系统越来越多,如何选择一款好用的工单系统成为了企业和团队需要考虑的问题。一款好用的工单系统应该能够满足实际工作场景的需求,提高工作效率和服务质量。本文将从以下5个方面探讨如何选择一款好用的工单系统。1、实际需求选择工单系统的第一步是明确实际需求......
  • 前端vue仿京东天猫简单好用的瀑布流瀑布流式布局列表组件waterfall
    前端vue仿京东天猫简单好用的瀑布流瀑布流式布局列表组件waterfall,下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id=13046效果图如下:使用方法<!--proList:条目数组数据goProDetail:条目点击事件跳转(实现了点击条目数据传值)--><ccWaterLis......