1. 程式人生 > >理解Arouter,實現Arouter基礎功能

理解Arouter,實現Arouter基礎功能

一 使用註解在編譯時將路徑的資料封裝在RouteMeta類中 並且在實現IRouteGroup類中 新增到引數atlas map中

特殊的類
@AutoService(Processor.class) 主要的作用是註解 processor類,並對其生成 META-INF 的配置資訊。
javapoet 幫助生成程式碼
IRouteGroup 生成的類實現了此介面 便於在執行時使用封裝的資料

二 初始化Arouter時 通過反射呼叫自動生成的類(繼承自IRouteGroup)的loadInto 方法把路徑和對應的類儲存到快取中

  ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
  className : 自動生成的類的路徑
  Warehouse.groupsIndex  : 快取的map

三 Arouter跳轉

通過path路徑去快取中找到對應的類做跳轉


*為什麼要分成兩個依賴module*  

    因為annotationProcessor project(':lib')  只參與編譯

    在android中寫註解一般分兩個module,一個是專門存放的註解類比如叫apt-lib,一個是註解解釋類比如叫apt-process,後一個依賴前一個。apt-lib提供api要打入apk的,apt-process只參與編譯。 
    apt-process中的build.gradle 

    compile project(':apt-lib') 

    app中的build.gradle 

    compile project(":apt-lib") 
    annotationProcessor project(':apt-process') 

建立步驟

一 建立
建立註解 java module:arouter_annotaion 建立route註解 RouteMeta封裝類

建立編譯時 java module : aroter_compiler 建立AutowiredProcessor類
需要引入
implementation ‘com.google.auto.service:auto-service:1.0-rc2’ //@AutoService(Processor.class) 呼叫
implementation ‘com.squareup:javapoet:1.7.0’ //幫助自動生成java類的依賴
需要依賴 arouter_annotaion module

   processor裡面主要兩個方法
     init()  初始化一些方法
     process()  解析註解 自動生成java類

建立api呼叫 android module : arouter_appi 創建出事Arouter類 IRouteGroup介面
需要依賴 arouter_annotaion module

二 使用

在app中引用上面三種module
annotationProcessor project(':aroter_compiler')
implementation project(':arouter_annotaion')
implementation project(':arouter_appi')

在aplication中 初始化
 Arouter.getInstance().init(getApplication());
在需要的頁面新增路由
  @Route(path = "ThreeActivity")
呼叫 Arouter.getInstance().build("ThreeActivity");

專案結構
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

相關類
arouter_annotaion module

package com.example.aroter_compiler;

import com.example.arouter_annotaion.Route;
import com.example.arouter_annotaion.RouteMeta;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import static javax.lang.model.element.Modifier.PUBLIC;

/**
 * Created by qf on 2018/7/25
 * 描述: AutowiredProcessor
 */
@AutoService(Processor.class)
public class AutowiredProcessor extends AbstractProcessor {


    private Filer mFiler;
    private Types mTypeUtils;
    private Elements mElementUtils;
    // System interface
    public static final String ACTIVITY = "android.app.Activity";

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        //初始化一些工具類
        mTypeUtils = processingEnv.getTypeUtils();
        mElementUtils = processingEnv.getElementUtils();
        mFiler = processingEnv.getFiler();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        System.out.println("ele====activity_");
        if (null != roundEnvironment) {
            Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(Route.class);
            doElements(elementsAnnotatedWith);
            return true;
        }
        return false;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new LinkedHashSet<>();
        annotations.add(Route.class.getCanonicalName());
        return annotations;
    }


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

    private void doElements(Set<? extends Element> elementsAnnotatedWith) {
        TypeMirror activityMirror = mElementUtils.getTypeElement(ACTIVITY).asType();


        //定義引數
        ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
                ClassName.get(Map.class),
                ClassName.get(String.class),
                ClassName.get(RouteMeta.class)
        );
        ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();


        //定義方法
        MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder("loadInto")
                .addAnnotation(Override.class)
                .addModifiers(PUBLIC)
                .addParameter(groupParamSpec);

        ClassName routeMetaCn = ClassName.get(RouteMeta.class);


        for (Element ele : elementsAnnotatedWith) {

            if (mTypeUtils.isSubtype(ele.asType(), activityMirror)) {
                System.out.println("ele====activity_" + ele.getSimpleName());
                Route annotation = ele.getAnnotation(Route.class);
                String path = annotation.path();
                ClassName className = ClassName.get((TypeElement) ele);


                /**
                 * atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap<String, Integer>(){{put("pac", 9); put("ch", 5); put("fl", 6); put("obj", 10); put("name", 8); put("dou", 7); put("boy", 0); put("objList", 10); put("map", 10); put("age", 3); put("url", 8); put("height", 3); }}, -1, -2147483648));
                 */
                loadIntoMethodOfGroupBuilder.addStatement(
                        "atlas.put($S, $T.build($T.class))",
                        path,
                        routeMetaCn,
                        className);
            }
            System.out.println("ele====" + ele.getSimpleName());
        }

        System.out.println("ele====over====");
        try {
            JavaFile.builder(
                    "com.qf.routes2",
                    TypeSpec.classBuilder("creteBySelf")
                            // doc
                            //.addJavadoc(WARNING_TIPS)
                            .addSuperinterface(ClassName.get(mElementUtils.getTypeElement("com.example.arouter_appi.IRouteGroup")))
                            .addModifiers(PUBLIC)
                            .addMethod(loadIntoMethodOfGroupBuilder.build())
                            .build()
            ).build().writeTo(mFiler);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

arouter_annotaion module

package com.example.arouter_annotaion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by qf on 2018/7/25
 * 描述: Route
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
    String path();
}
package com.example.arouter_annotaion;



/**
 * It contains basic route information.
 *
 * @author Alex <a href="mailto:[email protected]">Contact me.</a>
 * @version 1.0
 * @since 16/8/24 09:45
 */
public class RouteMeta {

    private Class<?> destination;   // Destination
    private String path;            // Path of route


    public RouteMeta(Class<?> cla) {
        this.destination = cla;
    }

    public RouteMeta(){}


    public Class<?> getDestination() {
        return destination;
    }

    public void setDestination(Class<?> destination) {
        this.destination = destination;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public static RouteMeta build(Class<?> destination) {
        return new RouteMeta(destination);
    }

}

arouter_appi module

package com.example.arouter_appi;

import android.app.Application;
import android.content.Intent;
import android.widget.Toast;

import com.example.arouter_annotaion.RouteMeta;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by qf on 2018/7/25
 * 描述: Arouter
 */
public class Arouter {

    private static Arouter arouter;

    public static Map<String, RouteMeta> arouters = new HashMap<>();

    private static Application mContext;

//    ARouter.getInstance().build("/simple/simple1Activity").navigation();

    private Arouter(){}

    public static Arouter  getInstance() {
        if (null == arouter) {
            arouter = new Arouter();
        }
        return arouter;
    }


    public void init(Application context) {
        mContext = context;
        try {
            ((IRouteGroup) (Class.forName("com.qf.routes2.creteBySelf").getConstructor().newInstance())).loadInto(arouters);

            Toast.makeText(mContext, arouters.size() + "", Toast.LENGTH_SHORT).show();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }



    public void build(String path) {
        RouteMeta routeMeta = arouters.get(path);
        if (null == routeMeta) return;

        Class<?> destination = routeMeta.getDestination();
        if (null != destination) {
            Intent intent = new Intent(mContext, destination);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }
    }


}
package com.example.arouter_appi;

import com.example.arouter_annotaion.RouteMeta;

import java.util.Map;

/**
 * Created by qf on 2018/7/25
 * 描述: IRouteGroup
 */
public interface IRouteGroup {
    /**
     * Fill the atlas with routes in group.
     */
    void loadInto(Map<String, RouteMeta> atlas);
}

相關推薦

理解Arouter,實現Arouter基礎功能

一 使用註解在編譯時將路徑的資料封裝在RouteMeta類中 並且在實現IRouteGroup類中 新增到引數atlas map中 特殊的類 @AutoService(Processor.class) 主要的作用是註解 processor類,並對

一起寫框架-Ioc內核容器的實現-基礎功能-ComponentScan支持組件註解限制(七)

name oid true int declare 修改 tac .cn 測試結果 實現功能 以上的代碼我們發現。我們都是將@ComponentScan掃描的路徑下的所有類都加載到容器中的。 而實際需求,我們並不希望所有的類都創建對象,而是加了組件註解@Controller

一起寫框架-MVC框架-基礎功能-實現forward和redirect的跳轉(四)

實現 java path subst velocity javax logs 兼容 lar 實現功能 當Controller的執行方法返回的視圖映射字符串是 “forward:/index.jsp”或者"/index.jsp":使用forw

日常學習隨筆-用鏈表的形式實現普通二叉樹的新增、查找、遍歷(前、中、後序)等基礎功能(側重源碼+說明)

新增 rabl super 例子 信息 count TP title 處理 一、二叉樹 1、二叉樹的概念 二叉樹是每個節點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree),其次序不能任意顛倒。 2、性質

安卓音、視頻播放功能簡單實現 --Android基礎

ket undle 顯示 perm err efault 繼續 bre mpat 1、音樂播放功能 關鍵代碼: MainActivity.java: package thonlon.example.cn.musicdemowithoutservice;import

spring boot 實現基礎的登陸註冊功能

spring boot 實現最基礎的登陸註冊功能: 首先先看程式碼:資料庫: 先說自己遇到的坑:第一:資料庫的配置是複製之前的資料庫,導致自己在另一個數據庫中查詢資料,這點大家在application.properties這個裡面注意下   這句 spring.dat

java操作pdf——基礎功能實現

正經學徒,佛系記錄,不搞事情 itextpdf 是java用於操作pdf檔案的工具,速度極快,目前測試上千頁的pdf檔案都不在話下 下面編寫的工具類,可看作是將pdf檔案轉成類似list的集合,通過對list的CURD操作,最終生成一個新的list集合,即生成一個新的pdf檔案 提供

LayaBox入門基礎之JS程式碼實現按鈕增加功能

2.2.3 實現List增加功能 ​ 實現List增加,需要用到LayaAir引擎laya.display.Sprite中的事件偵聽on()方法對滑鼠點選事件CLICK進行偵聽,以及laya.ui.List API中新增單元格資料來源的方法addItem(); ​ ​ (圖25) ​ 

深入理解ArrayList集合內部原理並自主封裝程式碼實現ArrayList集合功能

集合框架是java基礎學習中非常重要的一部分,學會集合用法的同時去了解一下集合內部程式碼實現原理對我們日後的java學習的幫助是十分大的;我們現在來了解一下ArrayList原理:ArrayList內部其實就是封裝一個預設固定大小的物件陣列;不過陣列的大小是可動

layui基礎2------layui實現表格編輯功能

頁面展示如下: 程式碼展示如下: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" %> <!DOCTY

hadoop--hdfs基礎功能實現

package hadoop; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import java.ne

OpenLayers3基礎教程之實現地圖顯示功能

1.配置開發環境 使用OpenLayers 3開發WebGIS應用,我們首先需要配置開發環境,首先我們需要在openlayers官網獲取OpenLayers 3的開發庫。下載連結:官網。開啟後如圖所示: 需要注意的是這裡下載有兩個版本,①:僅包括開

機器學習之深入理解神經網路理論基礎、BP演算法及其Python實現

  人工神經網路(Artificial Neural Networks,ANN)系統是 20 世紀 40 年代後出現的。它是由眾多的神經元可調的連線權值連線而成,具有大規模並行處理、分散式信 息儲存、良

關於無頭結點鏈表的創建算法及基礎功能打的實現

play temp 三方 頭指針 type malloc turn 元素 info 這裏是無頭結點的鏈表創建: 1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef str

前端基礎功能,原生js實現輪播圖例項教程

輪播圖是前端最基本、最常見的功能,不論web端還是移動端,大平臺還是小網站,大多在首頁都會放一個輪播圖效果。本教程講解怎麼實現一個簡單的輪播圖效果。學習本教程之前,讀者需要具備html和css技能,同時需要有簡單的javascript基礎。 本例項效果如下圖所示:    根據例項效果,需

7_1_Redis實現贊踩功能

hold reat sco aps mes esp oid 更新點 user 一、實現需求 1. 登錄賬號以後,在首頁home.html內可以點贊或者取消贊,只能點贊一次,點贊以後就不可再點贊; 取消贊以後為0. 2 點開news以後也可以點贊或者取消贊。

利用shell腳本實現計劃任務功能 V1.2

target 無需重啟 控制 basedir 之間 集中 shell腳本 htm 方便 2013.05.10 mytask 1.2   主程序休眠時間分成若幹小的時間片斷分段休眠,避免長時間的休眠不能及時響應系統信號。 2013.05.07 mytask 1

ztree實現權限功能(橫向顯示)

lose false 標記 console 多人 性能優化 發現 測試 func 最近在做權限功能的時候,采用的ztree實現的,但是產品要求最後一層的權限節點要橫向顯示。開始在網上找的解決方案是用css樣式把最後一層的display設置為inline。在我本地電腦上看了下

Shell 實現簡單計算器功能

shell 計算器Shell 實現簡單計算器功能,腳本如下:[[email protected]/* */ scripts]# cat jisuan.sh #!/bin/bash print_usage(){ printf $"USAGE:$0 NUM1 {+|-|*|/} NUM2\n"

脈沖雲基礎功能之版本控制

脈沖雲 版本控制 脈沖雲開發平臺 版本控制:如果說什麽是軟件開發項目一定要使用的基礎工具,那麽版本控制系統應該算最重要的部分。不管是個人開發或是團隊協作開發,都可以通過版本控制系統獲得巨大的好處。  沒有版本控制系統的話,代碼可能被別人或自己不小心覆蓋或遺失、也不知道是誰因為什麽原因改了這段代碼、