国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關(guān)于Apt注解實(shí)踐與總結(jié)【包含20篇博客】

gnehc / 2151人閱讀

摘要:使用實(shí)現(xiàn)功能運(yùn)行期注解案例使用簡單的注解,便可以設(shè)置布局,等效于使用實(shí)現(xiàn)路由綜合型案例比較全面的介紹從零起步,一步一步封裝簡易的路由開源庫。申明注解用的就是。返回值表示這個注解里可以存放什么類型值。

YCApt關(guān)于apt方案實(shí)踐與總結(jié) 目錄介紹

00.注解系列博客匯總

01.什么是apt

02.annotationProcessor和apt區(qū)別

03.項目目錄結(jié)構(gòu)

04.該案例作用

05.使用說明

06.編譯期注解生成代碼[點(diǎn)擊事件案例]

07.運(yùn)行期注解案例[setContentView案例]

08.使用注解替代枚舉

09.使用注解搭建路由[綜合案例]

9.1 搭建路由條件

9.2 通過注解去實(shí)現(xiàn)路由跳轉(zhuǎn)

9.3 自定義路由Processor編譯器

9.4 利用apt生成路由映射文件

9.5 路由框架的設(shè)計

9.6 路由參數(shù)的傳遞和接收

9.7 為何需要依賴注入

9.8 Activity屬性注入

9.9 路由開源庫的使用

關(guān)于apt實(shí)踐與總結(jié)開源庫地址 https://github.com/yangchong2... 00.注解系列博客匯總 0.1 注解基礎(chǔ)系列博客

01.Annotation注解詳細(xì)介紹

1.Annotation庫的簡單介紹
2.@Nullable和@NonNull
3.資源類型注釋
4.類型定義注釋
5.線程注釋
6.RGB顏色紙注釋
7.值范圍注釋
8.權(quán)限注釋
9.重寫函數(shù)注釋
10.返回值注釋
11.@Keep注釋
12.@SuppressWarnings注解
13.其他

[02.Dagger2深入分析,待更新]()

03.注解詳細(xì)介紹

什么是注解,注解分類有哪些?自定義注解分類?運(yùn)行注解案例展示分析,以一個最簡單的案例理解注解……使用注解替代枚舉,使用注解限定類型

04.APT技術(shù)詳解

什么是apt?理解注解處理器的作用和用途……android-apt被替代?annotationProcessor和apt區(qū)別? 什么是jack編譯方式?

06.自定義annotation注解

@Retention的作用?@Target(ElementType.TYPE)的解釋,@Inherited注解可以被繼承嗎?Annotation里面的方法為何不能是private?

07.注解之兼容kotlin

后期更新

08.注解之處理器類Processor

處理器類Processor介紹,重要方法,Element的作用,修飾方法的注解和ExecutableElement,了解修飾屬性、類成員的注解和VariableElement……

10.注解遇到問題和解決方案

無法引入javax包下的類庫,成功運(yùn)行一次,修改代碼后再運(yùn)行就報錯

11.注解代替枚舉

在做內(nèi)存優(yōu)化時,推薦使用注解代替枚舉,因?yàn)槊杜e占用的內(nèi)存更高,如何說明枚舉占用內(nèi)存高呢?這是為什么呢?

12.注解練習(xí)案例開源代碼

注解學(xué)習(xí)小案例,比較系統(tǒng)性學(xué)習(xí)注解并且應(yīng)用實(shí)踐。簡單應(yīng)用了運(yùn)行期注解,通過注解實(shí)現(xiàn)了setContentView功能;簡單應(yīng)用了編譯器注解,通過注解實(shí)現(xiàn)了防暴力點(diǎn)擊的功能,同時支持設(shè)置時間間隔;使用注解替代枚舉;使用注解一步步搭建簡單路由案例。結(jié)合相應(yīng)的博客,在來一些小案例,從此應(yīng)該對注解有更加深入的理解……

0.2 注解系列博客問題答疑

13.0.0.1 什么是注解?系統(tǒng)內(nèi)置的標(biāo)準(zhǔn)注解有哪些?SuppressWarnings用過沒?Android中提供了哪些與線程相關(guān)的注解?

13.0.0.2 什么是apt?apt的難點(diǎn)和優(yōu)勢?什么是注解處理器?抽象處理器中四個方法有何作用?annotationProcessor和apt區(qū)別?

13.0.0.3 注解是怎么分類的?自定義注解又是怎么分類的?運(yùn)行期注解原理是什么?實(shí)際注解案例有哪些?

13.0.0.4 在自定義注解中,Annotation里面的方法為何不能是private?Annotation里面的方法參數(shù)有哪些?

13.0.0.5 @Inherited是什么意思?注解是不可以繼承的,這是為什么?注解的繼承這個概念該如何理解?

13.0.0.6 什么是依賴注入?依賴注入案例舉例說明,有哪些方式,具備什么優(yōu)勢?依賴查找和依賴注入有什么區(qū)別?

13.0.0.7 路由框架為何需要依賴注入,不用的話行不行?路由用什么方式注入,這些注入方式各具何特點(diǎn),為何選擇注解注入?

13.0.0.8 實(shí)際開發(fā)中使用到注解有哪些,使用注解替代枚舉?如何通過注解限定傳入的類型?為何說枚舉損耗性能?

01.什么是apt

什么是apt

APT,就是Annotation Processing Tool的簡稱,就是可以在代碼編譯期間對注解進(jìn)行處理,并且生成Java文件,減少手動的代碼輸入。注解我們平時用到的比較多的可能會是運(yùn)行時注解,比如大名鼎鼎的retrofit就是用運(yùn)行時注解,通過動態(tài)代理來生成網(wǎng)絡(luò)請求。編譯時注解平時開發(fā)中可能會涉及的比較少,但并不是說不常用,比如我們經(jīng)常用的輪子Dagger2, ButterKnife, EventBus3 都在用,所以要緊跟潮流來看看APT技術(shù)的來龍去脈。

編譯時注解。

也有人叫它代碼生成,其實(shí)他們還是有些區(qū)別的,在編譯時對注解做處理,通過注解,獲取必要信息,在項目中生成代碼,運(yùn)行時調(diào)用,和直接運(yùn)行手寫代碼沒有任何區(qū)別。而更準(zhǔn)確的叫法:APT - Annotation Processing Tool

大概原理

Java API 已經(jīng)提供了掃描源碼并解析注解的框架,開發(fā)者可以通過繼承 AbstractProcessor 類來實(shí)現(xiàn)自己的注解解析邏輯。APT 的原理就是在注解了某些代碼元素(如字段、函數(shù)、類等)后,在編譯時編譯器會檢查 AbstractProcessor 的子類,并且自動調(diào)用其 process() 方法,然后將添加了指定注解的所有代碼元素作為參數(shù)傳遞給該方法,開發(fā)者再根據(jù)注解元素在編譯期輸出對應(yīng)的 Java 代碼

02.annotationProcessor和apt區(qū)別

annotationProcessor和apt區(qū)別

Android 官方的 annotationProcessor 同時支持 javac 和 jack 編譯方式,而 android-apt 只支持 javac 方式。當(dāng)然,目前 android-apt 在 Android Gradle 插件 2.2 版本上面仍然可以正常運(yùn)行,如果你沒有想支持 jack 編譯方式的話,可以繼續(xù)使用 android-apt。

目前比如一些常用框架dagger2,butterKnife,ARouter等,都支持annotationProcessor

什么是jack編譯方式?

Jack (Java Android Compiler Kit)是新的Android 編譯工具,從Android 6.0 開始加入,替換原有的編譯工具,例如javac, ProGuard, jarjar和 dx。它主要負(fù)責(zé)將java代碼編譯成dex包,并支持代碼壓縮,混淆等。

Jack工具的主要優(yōu)勢

完全開放源碼,源碼均在AOSP中,合作伙伴可貢獻(xiàn)源碼

加快編譯源碼,Jack 提供特殊的配置,減少編譯時間:pre-dexing, 增量編譯和Jack編譯服務(wù)器.

支持代碼壓縮,混淆,重打包和multidex,不在使用額外多帶帶的包,例如ProGuard。

03.項目目錄結(jié)構(gòu)

項目目錄結(jié)構(gòu)如圖:

app:Demo

AptAnnotation:java Library主要放一些項目中需要用到的自定義注解及相關(guān)代碼

AptApi:Android Library. 是我們真正對外發(fā)布并交由第三方使用的庫,它引用了apt-jar包

AptCompiler:java Library主要是應(yīng)用apt技術(shù)處理注解,生成相關(guān)代碼或者相關(guān)源文件,是核心所在。

04.該案例作用

前期僅僅是為了學(xué)習(xí),同時先讓demo運(yùn)行起來,雖然網(wǎng)上很多講解apt的博客寫的很詳細(xì),但是還是有必要結(jié)合實(shí)際案例練習(xí)一下。

使用apt實(shí)現(xiàn)點(diǎn)擊事件【編譯期注解生成代碼】

在一定時間內(nèi),按鈕點(diǎn)擊事件只能執(zhí)行一次。未到指定時間,不執(zhí)行點(diǎn)擊事件。

使用apt實(shí)現(xiàn)setContentView功能【運(yùn)行期注解案例】

使用簡單的注解,便可以設(shè)置布局,等效于setContentView(R.layout.activity_main)

使用apt實(shí)現(xiàn)路由【綜合型案例】

比較全面的介紹從零起步,一步一步封裝簡易的路由開源庫。一共用10篇博客記錄了大部分的過程,想要更加深入了解,歡迎clone該項目。

05.使用說明

如下所示

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //初始化OnceClick,并設(shè)置點(diǎn)擊事件間隔是2秒
    OnceInit.once(this,2000);
}

@OnceClick(R.id.tv_1)
public void Click1(){
    Log.d("tag--------------------","tv_1");
}

06.編譯期注解生成代碼

如下所示,在app/build/generated/source/apt/debug/MainActivity$$_Once_Proxy目錄下

// 編譯生成的代碼,不要修改
// 更多內(nèi)容:https://github.com/yangchong211
package com.ycbjie.ycapt;

import android.view.View;
import com.ycbjie.api.Finder;
import com.ycbjie.api.AbstractInjector;

public class MainActivity$$_Once_Proxy implements AbstractInjector {

    public long intervalTime;

    @Override
    public void setIntervalTime(long time) {
        intervalTime = time;
    }

    @Override
    public void inject(final Finder finder, final T target, Object source) {
        View view;
        view = finder.findViewById(source, 2131165325);
        if(view != null){
            view.setOnClickListener(new View.OnClickListener() {
            long time = 0L;
            @Override
            public void onClick(View v) {
                long temp = System.currentTimeMillis();
                if (temp - time >= intervalTime) {
                    time = temp;
                    target.Click1();
                }
            }});
        }
        view = finder.findViewById(source, 2131165326);
        if(view != null){
            view.setOnClickListener(new View.OnClickListener() {
            long time = 0L;
            @Override
            public void onClick(View v) {
                long temp = System.currentTimeMillis();
                if (temp - time >= intervalTime) {
                    time = temp;
                    target.Click2(v);
                }
            }});
        }
  }

}

07.運(yùn)行期注解案例

首先先定義自定義注解

//@Retention用來修飾這是一個什么類型的注解。這里表示該注解是一個運(yùn)行時注解。
@Retention(RetentionPolicy.RUNTIME)
//@Target用來表示這個注解可以使用在哪些地方。比如:類、方法、屬性、接口等等。
//這里ElementType.TYPE 表示這個注解可以用來修飾:Class, interface or enum declaration。
//當(dāng)你用ContentView修飾一個方法時,編譯器會提示錯誤。
@Target({ElementType.TYPE})
//這里的interface并不是說ContentView是一個接口。
//就像申明類用關(guān)鍵字class。申明枚舉用enum。申明注解用的就是@interface。
public @interface ContentView {
    //返回值表示這個注解里可以存放什么類型值。
    int value();
}

然后需要在activity中做注解解析

@SuppressLint("Registered")
public class ContentActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //注解解析
        //遍歷所有的子類
        for (Class c = this.getClass(); c != Context.class; c = c.getSuperclass()) {
            assert c != null;
            //找到修飾了注解ContentView的類
            ContentView annotation = (ContentView) c.getAnnotation(ContentView.class);
            if (annotation != null) {
                try {
                    //獲取ContentView的屬性值
                    int value = annotation.value();
                    //調(diào)用setContentView方法設(shè)置view
                    this.setContentView(value);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                }
                return;
            }
        }
    }
}

關(guān)于如何使用,注意你寫的Activity需要實(shí)現(xiàn)ContentActivity,才能讓注解生效

@ContentView(R.layout.activity_four)
public class FourActivity extends ContentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        findViewById(R.id.tv_1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(FourActivity.this,"運(yùn)行期注解",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

09.使用注解搭建路由[綜合案例]

9.1 ARouter路由解析

比較詳細(xì)地分析了阿里路由庫

9.1 搭建路由條件

為何需要路由?實(shí)現(xiàn)路由方式有哪些,這些方式各有何優(yōu)缺點(diǎn)?使用注解實(shí)現(xiàn)路由需要具備的條件以及簡單原理分析……

9.2 通過注解去實(shí)現(xiàn)路由跳轉(zhuǎn)

自定義Router注解,Router注解里有path和group,這便是仿照ARouter對路由進(jìn)行分組。然后看看注解生成的代碼,手寫路由跳轉(zhuǎn)代碼。

9.3 自定義路由Processor編譯器

Processor介紹,重要方法,Element的作用,修飾方法的注解和ExecutableElement

9.4 利用apt生成路由映射文件

在Activity類上加上@Router注解之后,便可通過apt來生成對應(yīng)的路由表,那么究竟是如何生成的代碼呢?

在組件化開發(fā)中,有多個module,為何要在build.gradle配置moduleName,又是如何通過代碼拿到module名稱?

process處理方法如何生成代碼的,又是如何寫入具體的路徑,寫入文件的?

看完這篇文章,應(yīng)該就能夠理解上面這些問題呢!

9.5 路由框架的設(shè)計和初始化

編譯期是在你的項目編譯的時候,這個時候還沒有開始打包,也就是你沒有生成apk呢!路由框架在這個時期根據(jù)注解去掃描所有文件,然后生成路由映射文件。這些文件都會統(tǒng)一打包到apk里,app運(yùn)行時期做的東西也不少,但總而言之都是對映射信息的處理,如執(zhí)行執(zhí)行路由跳轉(zhuǎn)等。那么如何設(shè)計框架呢?

生成的注解代碼,又是如何把這些路由映射關(guān)系拿到手,或者說在什么時候拿到手比較合適?為何注解需要進(jìn)行初始化操作?

如何得到得到路由表的類名,如何得到所有的routerAddress---activityClass映射關(guān)系?

[9.6 路由框架設(shè)計注意要點(diǎn)]()

需要注意哪些要點(diǎn)?

9.7 為何需要依賴注入

有哪些注入的方式可以解耦,你能想到多少?路由框架為何需要依賴注入?路由為何用注解進(jìn)行依賴注入,而不是用反射方式注入,或者通過構(gòu)造方法注入,或者通過接口方式注入?

9.8 Activity屬性注入

在跳轉(zhuǎn)頁面時,如何傳遞intent參數(shù),或者如何實(shí)現(xiàn)跳轉(zhuǎn)回調(diào)處理邏輯?

9.9 路由開源庫的使用

不帶參數(shù)直接跳轉(zhuǎn)

@Router(path = Path.six)
public class SixActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_six);
    }

}

ARouter.getsInstance().build(Path.six)
            .navigation(MainActivity.this, new NavigationCallback() {
        @Override
        public void onFound(Postcard postcard) {
            Log.e("NavigationCallback","找到跳轉(zhuǎn)頁面");
        }

        @Override
        public void onLost(Postcard postcard) {
            Log.e("NavigationCallback","未找到");
        }

        @Override
        public void onArrival(Postcard postcard) {
            Log.e("NavigationCallback","成功跳轉(zhuǎn)");
        }
    });

帶參數(shù)跳轉(zhuǎn)

@Router(path = Path.five)
public class FiveActivity extends AppCompatActivity {

    @Extra
    String title;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_five);
        //添加這行代碼,實(shí)際上就是自動生成了下面獲取參數(shù)值的代碼
        ARouter.getsInstance().inject(this);
        //如果不添加插入注解,則可以直接用下面的代碼。
        //Intent intent = getIntent();
        //String title = intent.getStringExtra("title");
        Toast.makeText(this, "title=" + title, Toast.LENGTH_SHORT).show();
    }

}

Bundle bundle = new Bundle();
bundle.putString("title","標(biāo)題-------------");
ARouter.getsInstance()
        .build(Path.five)
        .withBundle(bundle)
        .navigation();

路由注解生成的代碼位置

10.其他說明 00.參考案例

https://www.jianshu.com/p/335...

https://www.jianshu.com/p/200...

https://github.com/joyrun/Act...

https://github.com/BaronZ88/R...

https://github.com/alibaba/AR...

https://github.com/Xiasm/Easy...

https://github.com/chenenyu/R...

https://www.jianshu.com/p/8a3...

https://www.jianshu.com/p/e2d...

01.關(guān)于博客匯總鏈接

1.技術(shù)博客匯總

2.開源項目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關(guān)于我的博客

我的個人站點(diǎn):www.yczbj.org,www.ycbjie.cn

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國:https://my.oschina.net/zbj161...

泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

掘金:https://juejin.im/user/593943...

關(guān)于apt實(shí)踐與總結(jié)開源庫地址 https://github.com/yangchong2...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/73406.html

相關(guān)文章

  • APT案例之點(diǎn)擊事件

    摘要:楊充一定時間內(nèi)該點(diǎn)擊事件只能執(zhí)行一次用來修飾這是一個什么類型的注解。楊充自定義編譯器獲取遍歷,并生成代碼配置文件文件配置的作用是向系統(tǒng)注冊自定義注解處理器,執(zhí)行編譯時使用進(jìn)行處理。 目錄介紹 01.創(chuàng)建項目步驟 1.1 項目搭建 1.2 項目功能 02.自定義注解 03.創(chuàng)建Processor 04.compiler配置文件 05.編譯jar 06.如何使用 07.編譯生成代...

    cyixlq 評論0 收藏0
  • Android開源架構(gòu)

    摘要:音樂團(tuán)隊分享數(shù)據(jù)綁定運(yùn)行機(jī)制分析一個項目搞定所有主流架構(gòu)單元測試一個項目搞定所有主流架構(gòu)系列的第二個項目。代碼開源,展示了的用法,以及如何使用進(jìn)行測試,還有用框架對的進(jìn)行單元測試。 Android 常用三方框架的學(xué)習(xí) Android 常用三方框架的學(xué)習(xí) likfe/eventbus3-intellij-plugin AS 最新可用 eventbus3 插件,歡迎品嘗 簡單的 MVP 模...

    sutaking 評論0 收藏0
  • java

    摘要:多線程編程這篇文章分析了多線程的優(yōu)缺點(diǎn),如何創(chuàng)建多線程,分享了線程安全和線程通信線程池等等一些知識。 中間件技術(shù)入門教程 中間件技術(shù)入門教程,本博客介紹了 ESB、MQ、JMS 的一些知識... SpringBoot 多數(shù)據(jù)源 SpringBoot 使用主從數(shù)據(jù)源 簡易的后臺管理權(quán)限設(shè)計 從零開始搭建自己權(quán)限管理框架 Docker 多步構(gòu)建更小的 Java 鏡像 Docker Jav...

    honhon 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<