壹钟头搞明白注明处理器,MVC开发基础学习笔记

 

1、1个成效强大的页面开发协理类—HtmlHelper初叶询问

HTML扩充类的具备办法都有一个参数:
以textbox为例子
public static string TextBox( this HtmlHelper htmlHelper, string name,
Object value, IDictionary<string, Object> htmlAttributes )
public static string TextBox( this HtmlHelper htmlHelper, string name,
Object value, Object htmlAttributes )
那叁个参数代表那个html标签的个性集合。使用办法如下。
 
1.ActionLink
<%=Html.ActionLink(“那是三个接二连三”, “Index”, “Home”)%>
带有QueryString的写法
<%=Html.ActionLink(“那是2个总是”, “Index”, “Home”, new { page=一},null)%>
<%=Html.ActionLink(“那是叁个延续”, “Index”, new { page=一 })%>
有其它Html属性的写法
<%=Html.ActionLink(“那是3个老是”, “Index”, “Home”, new { id=”link一”
})%>
<%=Html.ActionLink(“那是三个接二连三”, “Index”,null, new { id=”link①”
})%>
QueryString与Html属性同时设有
<%=Html.ActionLink(“那是贰个接二连三”, “Index”, “Home”, new { page = 壹 },
new { id = “link一” })%>
<%=Html.ActionLink(“那是一个连连”, “Index” , new { page = 壹 }, new {
id = “link1” })%>
 
变化结果为:
<a href=”/”>那是二个连连</a>
带有QueryString的写法
<a href=”/?page=壹”>那是3个老是</a>
<a href=”/?page=一”>那是三个连连</a>
有此外Html属性的写法
<a href=”/?Length=四” id=”link一”>那是三个连连</a>
<a href=”/” id=”link一”>那是一个三番五次</a>
QueryString与Html属性同时存在
<a href=”/?page=1″ id=”link1″>这是3个几次三番</a>
<a href=”/?page=一” id=”link一”>那是3个总是</a>
 
2.RouteLink
跟ActionLink在效劳上同一。
<%=Html.RouteLink(“关于”, “about”, new { })%>
带QueryString
<%=Html.RouteLink(“关于”, “about”, new { page = 1 })%>
<%=Html.RouteLink(“关于”, “about”, new { page = 1 }, new { id =
“link1” })%>
 
变迁结果:
<a href=”/about”>关于</a>
<a href=”/about?page=1″>关于</a>
<a href=”/about?page=1″ id=”link1″>关于</a>
3.Form   2种方法
<%using(Html.BeginForm(“index”,”home”,FormMethod.Post)){%>
<%} %>
 
<%Html.BeginForm(“index”, “home”,
FormMethod.Post);//注意那里未有=输出%>
<%Html.EndForm(); %>
 
变更结果:
<form action=”/home/index” method=”post”></form>
4.TextBox
, Hidden ,
<%=Html.TextBox(“input1”) %>
<%=Html.TextBox(“input2”,Model.CategoryName,new{ @style =
“width:300px;” }) %>
<%=Html.TextBox(“input3”, ViewData[“Name”],new{ @style =
“width:300px;” }) %>
<%=Html.TextBoxFor(a => a.CategoryName, new { @style =
“width:300px;” })%>
 
扭转结果:
 
<input id=”input1″ name=”input1″ type=”text” value=”” />
<input id=”input2″ name=”input2″ style=”width:300px;” type=”text”
value=”Beverages” />
<input id=”input3″ name=”input3″ style=”width:300px;” type=”text”
value=”” />
<input id=”CategoryName” name=”CategoryName” style=”width:300px;”
type=”text” value=”Beverages” />
 
5.TextArea
<%=Html.TextArea(“input5”, Model.CategoryName, 3, 9,null)%>
<%=Html.TextAreaFor(a => a.CategoryName, 3, 3, null)%>
 
转移结果:
<textarea cols=”9″ id=”input5″ name=”input5″
rows=”3″>Beverages</textarea>
<textarea cols=”3″ id=”CategoryName” name=”CategoryName”
rows=”3″>Beverages</textarea>
 
6.CheckBox
<%=Html.CheckBox(“chk1”,true) %>
<%=Html.CheckBox(“chk1″, new { @class=”checkBox”}) %>
<%=Html.CheckBoxFor(a =>a.IsVaild, new { @class = “checkBox”
})%>
 
转变结果:
 
壹钟头搞明白注明处理器,MVC开发基础学习笔记。<input checked=”checked” id=”chk1″ name=”chk1″ type=”checkbox”
value=”true” /><input name=”chk1″ type=”hidden” value=”false”
/>
 
<input class=”checkBox” id=”chk1″ name=”chk1″ type=”checkbox”
value=”true” /><input name=”chk1″ type=”hidden” value=”false”
/>
 
<input checked=”checked” class=”checkBox” id=”IsVaild” name=”IsVaild”
type=”checkbox” value=”true” /><input name=”IsVaild” type=”hidden”
value=”false” />
 
7.ListBox
<%=Html.ListBox(“lstBox1”,(SelectList)ViewData[“Categories”])%>
<%=Html.ListBoxFor(a => a.CategoryName,
(SelectList)ViewData[“Categories”])%>
 
浮动结果:
<select id=”lstBox1″ multiple=”multiple” name=”lstBox1″>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option selected=”selected” value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
<select id=”CategoryName” multiple=”multiple”
name=”CategoryName”>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
 
8.DropDownList
<%= Html.DropDownList(“ddl1”,
(SelectList)ViewData[“Categories”],  “–Select One–“)%>
<%=Html.DropDownListFor(a => a.CategoryName,
(SelectList)ViewData[“Categories”], “–Select One–“, new { @class =
“dropdownlist” })%>
 
变更结果:
<select id=”ddl1″ name=”ddl1″>
<option value=””>–Select One–</option>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option selected=”selected” value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
<select class=”dropdownlist” id=”CategoryName”
name=”CategoryName”>
<option value=””>–Select One–</option>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
 
九.Partial
视图模板
webform里叫自定义控件。功用都以为了复用。但利用上自定义控件真的很难用好。
<% Html.RenderPartial(“DinnerForm”);
%>  看精晓了并未有等号的。

Java中的注解是个很神奇的东西,还不打听的可以看下一钟头搞掌握自定义注解(Annotation)。未来无数Android的库都用利用注脚达成的,比如ButterKnife,大家不防也来学学一下,学完注明处理器,我们品尝写二个粗略的切近ButterKnife的东西来绑定控件。

群里一小伙伴在开发应用软件时相遇了难点,便截图提问

1.一 有失必有得

美高梅开户网址 1

  在ASP.Net
MVC中微软并未有提供类似服务器端控件那种开发方式,究竟微软的MVC便是价值观的哀告处理响应的回归。所以遗弃以前的那种事件响应的模子,放弃服务器端控件也当然。

  但是,假设手写Html标签功能又相比低,可重成本相比较低。那时,大家该怎么来提升功能呢?首先,经过上篇大家领略能够透过ViewData传递数据,于是我们能够写出以下的Html代码:

<input name="UserName" type="text" value="<%: ViewData["UserName"] %>" />

  即使以上代码能够化解难题,不过效用依旧比较低,特别是在列表集合项较多的时候,工作量会比较大。那么,还有木有一种越来越好的不二等秘书籍吗?别急,微软现已为大家想好了策略。微软为开发职员神速支付前台页面提供了添加的HtmlHelper的声援类,帮助大家飞快支付前台页面,也提供了可扩展的接口,前台页面包车型地铁价签能够能够完结高度可采用

什么是申明处理器?

评释处理器是(Annotation Processor)是javac的2个工具,用来在编写翻译时扫描和编写翻译和处理申明(Annotation)。你能够协调定义证明和注释处理器去搞壹些政工。一个诠释处理器它以Java代码或许(编写翻译过的字节码)作为输入,生成文书(经常是java文件)。这个生成的java文件不可能改改,并且会同其手动编写的java代码壹样会被javac编写翻译。看到那里丰盛在此以前知道,应该知道大致的进度了,就是把标记了诠释的类,变量等作为输入内容,经过申明处理器处理,生成想要生成的java代码。

美高梅开户网址 2

1.2 HtmlHelper初窥

  大家得以由此在页面中经过Html.XXX来兑现快捷的Html标签编辑,并且能够1本万利地拓展数据绑定。

<%: Html.Raw("<p>Hello,I am HtmlHelper!</p>") %>

  那么,为何能够在页面中调用Html.XXX方法吧?通过ILSpy反编写翻译ViewPage页,大家得以看来原来在ViewPage下有一个HtmlHelper类型的品质-Html。(那下终于明白,为何能够在页面中使用Html.xxxx()了)

美高梅开户网址 3

  那么这几个HtmlHelper类又是2个怎么着类型的大神啊?继续反编写翻译查看,在System.Web.Mvc命名空间下的HtmlHelper类型如下图所示,经过MSDN大神的教学,HtmlHelper帮衬在视图中显现
HTML
控件。那我们看看在此类中有木有遗闻中的TextBox、CheckBox的章程吧?经查阅,木有。

美高梅开户网址 4

  那么,大家怎么可以在页面中央银行使Html.TextBox()方法吗?那里就涉及到三个叫作“扩张方法”的东东了,HtmlHelper 类的扩大方法在 System.Web.Mvc.Html
命名空间中。 那个扩展添加了用来创制窗体、显示 HTML
控件、显示分部视图、执行输入验证等效果的补助器方法。那么,有关怎样自定义扩充方法请参阅本文第1片段,那里先卖个枢纽,暂不介绍。

美高梅开户网址 5

美高梅开户网址 ,处理器AbstractProcessor

电脑的写法有固定的老路,继承AbsstractProcessor。如下:

public class MyProcessor extends AbstractProcessor {
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv){
        super.init(processingEnv);
    }
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return null;
    }
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return true;
    }
}
  • init(ProcessingEnvironment processingEnv)
    被诠释处理工科具调用,参数ProcessingEnvironment
    提供了Element,Filer,Messager等工具
  • getSupportedAnnotationTypes()
    内定申明处理器是登记给那么些诠释的,它是一个字符串的联谊,意味着能够支撑七个项指标表明,并且字符串是合法全名。
  • getSupportedSourceVersion 指定Java版本
  • process(Set<? extends TypeElement> annotations,
    RoundEnvironment roundEnv)
    那一个也是最根本的,在此处扫描和处理你的表明并生成Java代码,新闻都在参数RoundEnvironment
    里了,后边会介绍。

在Java7 中还足以选用

@SupportedSourceVersion(SourceVersion.latestSupported())
@SupportedAnnotationTypes({
   // 合法注解全名的集合
 })

代表 getSupportedSourceVersion() 和 getSupportedAnnotationType()
,没毛病,还足以在诠释处理离器中选取申明。

1、傻瓜式消除办法:

一.叁 为啥使用HtmlHelper?

   思量那样1个现象:大家的体系第三个版本中的路由规则是如此的{controller}/{action}/{id},于是我们项目中装有的<a>标签所指向的都以以刚刚的条条框框命名的href(例如:<a
></a>)。不过在其次版中,我们的路由规则也会化为了{controller}-{action}-{id},那么大家正好为超链接所设置的href便都爱莫能助常常访问了。那时,大家供给举行轮换,单个替换或批量轮换(例如改为:<a
></a>),纵然也足以缓解难题,可是属实扩张了工作量,功用相当低。

  那么,如何来遮掩这种转变所推动的困顿呢?那里,通过行使HtmlHelper为大家提供的ActionLink标签,便足以缓解这些题材。因为HtmlHelper是从服务器端自动帮您生成a标签,由此所生成的href会遵从近日的路由规则,也就帮大家遮挡了转变,提升了工效。

登记评释处理器

打包注明处理器的时候须求2个异样的文件
javax.annotation.processing.Processor 在 META-INF/services 路径下

--myprcessor.jar
----com
------example
--------MyProcessor.class
----META-INF
------services
--------javax.annotation.processing.Processor

包装进javax.annotation.processing.Processor的剧情是计算机的法定全称,八个电脑之间换行。

com.example.myprocess.MyProcessorA
com.example.myprocess.MyProcessorB

google提供了贰个登记处理器的库

compile 'com.google.auto.service:auto-service:1.0-rc2'

3个诠释化解:

@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
      ...
}

读到那里ButterKnife用到的知识点我们都已经精通了
一.自定义注明
贰.用申明处理器解析阐明
3.分析完毕后生成Java文件
BufferKnife使用:

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.rxjava_demo)
    Button mRxJavaDemo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mRxJavaDemo.setText("Text");
    }

}

下一场我们编写翻译一下,打开路径:/app/build/intermediates/classes/release/com/ming/rxdemo/MainActivity$$ViewBinder.class
那正是大家转移的Java文件,能够看来Button已经在bind里面初阶化了。

public class MainActivity$$ViewBinder<T extends MainActivity> implements ViewBinder<T> {
    public MainActivity$$ViewBinder() {
    }

    public void bind(Finder finder, T target, Object source) {
        View view = (View)finder.findRequiredView(source, 2131492944, "field \'mRxJavaDemo\'");
        target.mRxJavaDemo = (Button)finder.castView(view, 2131492944, "field \'mRxJavaDemo\'");
    }

    public void unbind(T target) {
        target.mRxJavaDemo = null;
    }
}

接下去大家创造三个品种,写多少个简练的用注明绑定控件的例子

  删除:

二、未有服务器控件也能干大事—HtmlHelper主要艺术介绍

  PS:那里的实例均未有加<% %>或@符号,要运维请自行加上。

  (1)ActionLink与RouteLink

Html.ActionLink("这是一个连接", "Index", "Home")  带有QueryString的写法  Html.ActionLink("这是一个连接", "Index", "Home", new { page=1 },null)  Html.ActionLink("这是一个连接", "Index", new { page=1 })  有其它Html属性的写法  Html.ActionLink("这是一个连接", "Index", "Home", new { id="link1" })  Html.ActionLink("这是一个连接", "Index",null, new { id="link1" })  QueryString与Html属性同时存在  Html.ActionLink("这是一个连接", "Index", "Home", new { page = 1 }, new { id = "link1" })  Html.ActionLink("这是一个连接", "Index" , new { page = 1 }, new { id = "link1" })

  其变动的结果为:

<a href="/">这是一个连接</a>  带有QueryString的写法  <a href="/?page=1">这是一个连接</a>  <a href="/?page=1">这是一个连接</a>  有其它Html属性的写法  <a href="/?Length=4" id="link1">这是一个连接</a>  <a href="/" id="link1">这是一个连接</a>  QueryString与Html属性同时存在  <a href="/?page=1" id="link1">这是一个连接</a>  <a href="/?page=1" id="link1">这是一个连接</a>

  RouteLink在用法大概与ActionLink1致,那里就不再介绍,详情请出席MSDN;

  (2)TextBox与TextArea

  ①TextBox

Html.TextBox("input1")   Html.TextBox("input2",Model.CategoryName,new{ @style = "width:300px;" })   Html.TextBox("input3", ViewData["Name"],new{ @style = "width:300px;" })   Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" })

  其生成的结果为:

<input id="input1" name="input1" type="text" value="" />  <input id="input2" name="input2" style="width:300px;" type="text" value="Beverages" />  <input id="input3" name="input3" style="width:300px;" type="text" value="" />  <input id="CategoryName" name="CategoryName" style="width:300px;" type="text" value="Electronic" />

  ②TextArea

Html.TextArea("input5", Model.CategoryName, 3, 9,null)  Html.TextAreaFor(a => a.CategoryName, 3, 3, null)

  其转移的结果为:

<textarea cols="9" id="input5" name="input5" rows="3">Electronic</textarea>  <textarea cols="3" id="CategoryName" name="CategoryName" rows="3">Electronic</textarea>

  那里能够看看,我们能够动用强类型来生成Html标签,例如:Html.Text博克斯For(a
=> a.CategoryName, new { @style = “width:300px;”
}),那里的CategoryName就是某些项目标习性。

  (3)CheckBox

Html.CheckBox("chk1",true)   Html.CheckBox("chk1", new { @class="checkBox"})   Html.CheckBoxFor(a =>a.IsVaild, new { @class = "checkBox" })

   其变动的结果为:

<input checked="checked" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />  <input class="checkBox" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />  <input checked="checked" class="checkBox" id="IsVaild" name="IsVaild" type="checkbox" value="true" /><input name="IsVaild" type="hidden" value="false" />

  (4)DropDownList

Html.DropDownList("ddl1", (SelectList)ViewData["Categories"],  "--Select One--")  Html.DropDownListFor(a => a.CategoryName, (SelectList)ViewData["Categories"], "--Select One--", new { @class = "dropdownlist" })

  其生成的结果为:

<select id="ddl1" name="ddl1">  <option value="">--Select One--</option>  <option value="1">Beverages</option>  <option value="2">Condiments</option>  <option selected="selected" value="3">Confections</option>  <option value="4">Dairy Products</option>  <option value="5">Grains/Cereals</option>  <option value="6">Meat/Poultry</option>  <option value="7">Produce</option>  <option value="8">Seafood</option>  </select>  <select class="dropdownlist" id="CategoryName" name="CategoryName">  <option value="">--Select One--</option>  <option value="1">Beverages</option>  <option value="2">Condiments</option>  <option value="3">Confections</option>  <option value="4">Dairy Products</option>  <option value="5">Grains/Cereals</option>  <option value="6">Meat/Poultry</option>  <option value="7">Produce</option>  <option value="8">Seafood</option>  </select>

  (5)RadioButton

男<%: Html.RadioButton("Gender","1",true) %>  女<%: Html.RadioButton("Gender","2",false) %>

  其变动的代码为:

男<input checked="checked" id="Gender" name="Gender" type="radio" value="1" />  女<input id="Gender" name="Gender" type="radio" value="2" />

  (6)Encode与Raw

  Encode会将内容实行编码话,因而,如若您的剧情中富含Html标签的话那么会被分析成特殊字符,例如:

<%: Html.Encode("<p>哈哈</p>") %>

  其变动的代码为:

&amp;lt;p&amp;gt;哈哈&amp;lt;/p&amp;gt;

  那里关键是为了防范XSS攻击和恶意脚本,由此在MVC中,暗中同意的<%:
%>就兑现了<%: Html.Encode()
%>。然而,有些时候即使我们须求输出Html或JavaScript内容的字符串,那时我们能够运用HtmlHelper为大家提供的别的艺术。例如我们要出口刚刚那句话,大家能够如下使用:

<%: Html.Raw("<p>哈哈</p>") %>

  其转移的代码为:

<p>哈哈</p>

  在HtmlHelper中还提供了不少的扩大方法供我们有利创立Html,比如:BeginForm、EndForm等。关于任何的法门介绍,请自行检索,那里不再一一赘述。

品种协会

--apt-demo
----bindview-annotation(Java Library)
----bindview-api(Android Library)
----bindview-compiler(Java Library)
----app(Android App)
  • bindview-annotation 申明申明
  • bindview-api 调用Android SDK API
  • bindview-compiler 申明处理器相关
  • app 测试App

1.在 bindview-annotation
下创制一个@BindView评释,该注解重返三个值,整型,名称为value,用来代表控件ID。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
    /**
     * 用来装id
     *
     * @return
     */
    int value();
}

贰.在 bindview-compiler 中创造证明处理器 BindViewProcessor
并注册,做基本的起始化学工业作。

@AutoService(Processor.class)
public class BindViewProcessor extends AbstractProcessor {
    /**
     * 文件相关的辅助类
     */
    private Filer mFiler;
    /**
     * 元素相关的辅助类
     */
    private Elements mElementUtils;
    /**
     * 日志相关的辅助类
     */
    private Messager mMessager;
    /**
     * 解析的目标注解集合
     */
    private Map<String, AnnotatedClass> mAnnotatedClassMap = new HashMap<>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mElementUtils = processingEnv.getElementUtils();
        mMessager = processingEnv.getMessager();
        mFiler = processingEnv.getFiler();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new LinkedHashSet<>();
        types.add(BindView.class.getCanonicalName());//返回该注解处理器支持的注解集合
        return types;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return true;
    }
}

是还是不是小心到了里面有个Map容器,而且档次是AnnotatedClass,这是干啥的啊?这些很好精晓,咱们在解析XML,解析Json的时候数据解析完之后是或不是要以对象的样式表示出来,那里也同等,@BindView用来标记类成员,2个类下能够有八个成员,好比1个Activity中能够有四个控件,3个容器下有八个控件等。如下:

package com.mingwei.myprocess.model;

import com.mingwei.myprocess.TypeUtil;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/**
 * Created by mingwei on 12/10/16.
 * CSDN:    http://blog.csdn.net/u013045971
 * Github:  https://github.com/gumingwei
 */
public class AnnotatedClass {
    /**
     * 类名
     */
    public TypeElement mClassElement;
    /**
     * 成员变量集合
     */
    public List<BindViewField> mFiled;
    /**
     * 元素辅助类
     */
    public Elements mElementUtils;

    public AnnotatedClass(TypeElement classElement, Elements elementUtils) {
        this.mClassElement = classElement;
        this.mElementUtils = elementUtils;
        this.mFiled = new ArrayList<>();
    }
    /**
     * 获取当前这个类的全名
     */
    public String getFullClassName() {
        return mClassElement.getQualifiedName().toString();
    }
    /**
     * 添加一个成员
     */
    public void addField(BindViewField field) {
        mFiled.add(field);
    }
    /**
     * 输出Java
     */
    public JavaFile generateFinder() {
        return null;
    }
    /**
     * 包名
     */
    public String getPackageName(TypeElement type) {
        return mElementUtils.getPackageOf(type).getQualifiedName().toString();
    }
    /**
     * 类名
     */
    private static String getClassName(TypeElement type, String packageName) {
        int packageLen = packageName.length() + 1;
        return type.getQualifiedName().toString().substring(packageLen).replace('.', '$');
    }
}

成员用BindViewField表示,没什么复杂的逻辑,在构造函数判断项目和初步化,不难的get函数

package com.mingwei.myprocess.model;

import com.mingwe.myanno.BindView;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;

/**
 * Created by mingwei on 12/10/16.
 * CSDN:    http://blog.csdn.net/u013045971
 * Github:  https://github.com/gumingwei
 * 被BindView注解标记的字段的模型类
 */
public class BindViewField {

    private VariableElement mFieldElement;

    private int mResId;

    public BindViewField(Element element) throws IllegalArgumentException {
        if (element.getKind() != ElementKind.FIELD) {//判断是否是类成员
            throw new IllegalArgumentException(String.format("Only field can be annotated with @%s",
                    BindView.class.getSimpleName()));
        }
        mFieldElement = (VariableElement) element;
        //获取注解和值
        BindView bindView = mFieldElement.getAnnotation(BindView.class);
        mResId = bindView.value();
        if (mResId < 0) {
            throw new IllegalArgumentException(String.format("value() in %s for field % is not valid",
                    BindView.class.getSimpleName(), mFieldElement.getSimpleName()));
        }
    }

    public Name getFieldName() {
        return mFieldElement.getSimpleName();
    }

    public int getResId() {
        return mResId;
    }

    public TypeMirror getFieldType() {
        return mFieldElement.asType();
    }
}

此间看看了许多的Element,在Xml解析时候就有Element这些概念。在Java源文件中平等有Element概念:

package com.example;        // PackageElement

public class MyClass {      // TypeElement

    private int a;          // VariableElement

    private Foo other;      // VariableElement

    public Foo () {}        // ExecuteableElement

    public void setA (      // ExecuteableElement
                int newA    // TypeElement
                ) {

    }
}

接下去就是在电脑的process中分析注解了
每一回解析前都要清空,因为process方法可能不止走一回。
获得表明模型之后遍历调用生成Java代码

@Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        mAnnotatedClassMap.clear();
        try {
            processBindView(roundEnv);
        } catch (IllegalArgumentException e) {
            error(e.getMessage());
            return true;
        }

        try {
            for (AnnotatedClass annotatedClass : mAnnotatedClassMap.values()) {
                info("generating file for %s", annotatedClass.getFullClassName());
                annotatedClass.generateFinder().writeTo(mFiler);
            }
        } catch (Exception e) {
            e.printStackTrace();
            error("Generate file failed,reason:%s", e.getMessage());
        }
        return true;
    }

processBindView 和 getAnnotatedClass

    /**
     * 遍历目标RoundEnviroment
     * @param roundEnv
     */
    private void processBindView(RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {
            AnnotatedClass annotatedClass = getAnnotatedClass(element);
            BindViewField field = new BindViewField(element);
            annotatedClass.addField(field);
        }
    }
    /**
     * 如果在map中存在就直接用,不存在就new出来放在map里
     * @param element
     */
    private AnnotatedClass getAnnotatedClass(Element element) {
        TypeElement encloseElement = (TypeElement) element.getEnclosingElement();
        String fullClassName = encloseElement.getQualifiedName().toString();
        AnnotatedClass annotatedClass = mAnnotatedClassMap.get(fullClassName);
        if (annotatedClass == null) {
            annotatedClass = new AnnotatedClass(encloseElement, mElementUtils);
            mAnnotatedClassMap.put(fullClassName, annotatedClass);
        }
        return annotatedClass;
    }

三.在生成Java以前 大家要在bindview-api 中开创1些类,合营bindview-compiler 1起使用。
您在应用Butterknife的时候不是要在onCreate里掉用一下BindView.bind(this)吗,那这家伙是干什么呢。试想一下,前边做的一大堆工作是为着转变自动绑定控件的Java代码,如果生成的Java代码不能和你要采纳的地点论及起来,那也是未有用的,能够把BindView.bind(this)驾驭为调用了您转移的Java代码,而生成了代码中成功了一部分控件的伊始化学工业作,自然你的控件就变得可用了。
接口:Finder 定义findView方法
实现类:ActivityFinder Activity中使用,ViewFinder View中使用
接口:Injector
inject方法以后是要成立在变幻无常的Java文件中,用该方法中传送过来的参数实行控件的起首化。
帮忙类:ViewInjector 调用和传递参数
那个代码小编就不贴了,就一丢丢情节,一看就清楚了。
4.在AnnotatedClass中生成Java代码
转变代码应用了3个很好用的库 Javapoet
。类,方法,都可以接纳营造器塑造出来,很好上手,再也不用拼接字符串了。哈哈哈哈~

public JavaFile generateFinder() {
        //构建方法
        MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder("inject")
                .addModifiers(Modifier.PUBLIC)//添加描述
                .addAnnotation(Override.class)//添加注解
                .addParameter(TypeName.get(mClassElement.asType()), "host", Modifier.FINAL)//添加参数
                .addParameter(TypeName.OBJECT, "source")//添加参数
                .addParameter(TypeUtil.FINDER, "finder");//添加参数

        for (BindViewField field : mFiled) {
            //添加一行
            injectMethodBuilder.addStatement("host.$N=($T)finder.findView(source,$L)", field.getFieldName()
                    , ClassName.get(field.getFieldType()), field.getResId());
        }

        String packageName = getPackageName(mClassElement);
        String className = getClassName(mClassElement, packageName);
        ClassName bindClassName = ClassName.get(packageName, className);
        //构建类
        TypeSpec finderClass = TypeSpec.classBuilder(bindClassName.simpleName() + "$$Injector")//类名
                .addModifiers(Modifier.PUBLIC)//添加描述
                .addSuperinterface(ParameterizedTypeName.get(TypeUtil.INJECTOR, TypeName.get(mClassElement.asType())))//添加接口(类/接口,范型)
                .addMethod(injectMethodBuilder.build())//添加方法
                .build();

        return JavaFile.builder(packageName, finderClass).build();
    }

    public String getPackageName(TypeElement type) {
        return mElementUtils.getPackageOf(type).getQualifiedName().toString();
    }

    private static String getClassName(TypeElement type, String packageName) {
        int packageLen = packageName.length() + 1;
        return type.getQualifiedName().toString().substring(packageLen).replace('.', '$');
    }

可以在代码里System.out调节和测试表明处理器的代码。
还要小心的有个别,项目里面包车型大巴互相引用。
bindview-complier 引用 bindview-annotation
app 引用了剩余的七个module,在引用 bindview-complier 的时候用的apt的艺术

apt project(':bindview-compiler')

就写到那里吧,Demo
放在 Github上了

  ((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).EndInit();

三、随时四处小编也能扩展—HtmlHelper扩张方法简介

  这一个方法尽管简单易行,可是会出错。

三.壹 增加方法简介

  借助MSDN的介绍:“扩展方法使你可以向现有项目“添加”方法,而无需创立新的派生类型、重新编写翻译或以其余方法修改原始类型。”扩大方法是①种分外的静态方法,但足以像扩张项目上的实例方法同样实行调用。大家能够回到第二局地对HtmlHelper的扩大类-InputExtension类上,它是对于HtmlHelper的恢弘,那么怎么辨识它是HtmlHelper的恢宏呢?

  原因是,当您添加performanceCounte之类的控件时,它会必要生成CategoryName,但VS突然犯傻,未有自动生成CategoryName,所以报了错。(CategoryName指的正是控件要用的名字)

三.二 扩大方法的叁要素

美高梅开户网址 6

  (1)静态类

  能够从上海体育地方看出,InputExtension首先是四个静态类;

  (2)静态方法

  既然是静态类,那么其兼具的格局肯定都以静态方法,例如:public
static MvcHtmlString CheckBox();

  (3)this关键字

  可以从章程名定义中看出,第二个参数都是this
HtmlHelper htmlHelper,代表对HtmlHelper类的恢弘;

 

三.3 自定义扩大方法

  (一)在Models文件夹下新建三个类,取名称为:MyHtmlHelperExt

  (贰)将MyHtmlHelperExt设置为static,并写入以下的三个静态方法:

public static HtmlString MyExtHtmlLabel(this HtmlHelper helper, string value)  {        return new HtmlString(string.Format("Hello-{0}-End", value));  }

  (3)鲜明满意了扩张方法的3要素之后,将命名空间改为:System.Web.Mvc。

namespace System.Web.Mvc

data-source=”Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.”>PS:为什么要改命名空间为System.Web.Mvc?

data-source=”Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.”>那是因为一旦不改命名空间,大家要运用自定义的壮大方法须要在种种页面中引进Models(MyHtmlHelper所在的13分命名空间)那个命名空间,为了防止再度的命名空间引进操作(想想大家应用Html.TextBox()不也未有引进命名空间么?),于是大家将命名空间与HtmlHelper类所在的命名空间保持一致。

  (四)在页面中大家就能够运用大家友好写的壮大方法了

<%: Html.MyExtHtmlLabel("EdisonChou") %>

  (5)查看页面效果

美高梅开户网址 7

2、安妥的消除办法

参照小说

(1)马伦,《ASP.Net
MVC视频教程》,

(二)oer,《HtmlHelper使用全称》,

(3)MSDN,《扩张方法(C#编制程序指南)》,

(4)MSDN,《HtmlHelper类(System.Web.Mvc)》,

 

作者:周旭龙

出处:

本文版权归小编和和讯共有,欢迎转发,但未经我同意必须保留此段申明,且在文章页面鲜明地方给出原来的书文链接。


  在Form1.Designer中添加
    this.performanceCounter1.CategoryName = “Processor”;
    this.performanceCounter1.CounterName = “% Processor Time”;
    this.performanceCounter1.InstanceName = “_Total”;

  

 

————————————假装那是3个分割线————————————

美高梅开户网址 8

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图