精华内容
下载资源
问答
  • 是ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,提倡的是简单且够用。 2、原生的路由方案存在的问题 首先谈一谈原生的路由方案存在的问题以及为什么需要路由框架。我们所使用的原生路由...
  • 新版的android sdk集成了eclipse,只用下载android sdk,安装jdk并设置环境变量就可以进行安卓环境配置了百度中搜索“android sdk”第一个地址,则得到http://developer.android.com/,这里去下载android sdk2、ADT...

    在调试Android程序的过程中,发现Android并没有类似于linux的Traceroute的功能,于是写利用ping写了一个Android版的traceroute

    展开全文
  • 一:golang自带路由介绍golang...这个实现比较简单,有一些缺点:不支持参数设定,例如/user/:uid 这种泛型类型匹配无法很友好的支持REST模式,无法限制访问方法(POST,GET等)也不支持正则二:gorilla/mux路由上面...

    一:golang自带路由介绍

    golang自带路由库 http.ServerMux ,实际上是一个 map[string]Handler,是请求的url路径和该url路径对于的一个处理函数的映射关系。这个实现比较简单,有一些缺点:

    不支持参数设定,例如/user/:uid 这种泛型类型匹配无法很友好的支持REST模式,无法限制访问方法(POST,GET等)也不支持正则

    二:gorilla/mux路由

    上面所指出来的glang自带路由的缺点,gorilla/mux 都具备,而且还兼容 http.ServerMux。除了支持路径正则,命名路由,还支持中间件等等功能。所以mux是一个短小精悍,功能很全的路由。

    1. 普通路由

    示例 demo1.go

    package main

    import (

    "fmt"

    "github.com/gorilla/mux"

    "net/http"

    )

    func main() {

    r := mux.NewRouter()

    //普通路由

    r.HandleFunc("/", IndexHandler)

    r.HandleFunc("/products", ProductsHandler)

    http.ListenAndServe(":8080", r)

    }

    func IndexHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "hello world")

    }

    func ProductsHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "hello, Products")

    }

    上面mux的普通路由是不是似曾相识,跟golang标准库用法一样

    2. 参数路由

    参数路由,可以是普通路由,还可以是正则匹配

    示例 demo2.go:

    package main

    import (

    "net/http"

    "fmt"

    "github.com/gorilla/mux"

    )

    //路由参数

    func main() {

    r := mux.NewRouter()

    //1. 普通路由参数

    // r.HandleFunc("/articles/{title}", TitleHandler)

    //2. 正则路由参数,下面例子中限制为英文字母

    r.HandleFunc("/articles/{title:[a-z]+}", TitleHandler)

    http.ListenAndServe(":8080", r)

    }

    //https://github.com/gorilla/mux#examples

    func TitleHandler(w http.ResponseWriter, r *http.Request) {

    vars := mux.Vars(r) // 获取参数

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "title: %v\n", vars["title"])

    }

    第1个普通路由参数,就是啥参数都可以,不管是字母,数字,还是中文等

    第2个正则路由参数,限制了只能是英文字母,否则会报 404 page not found

    3. 路由匹配Matching Routes

    3.1 匹配host

    r := mux.NewRouter()

    //只匹配 www.example.com

    r.Host("www.example.com")

    // 动态匹配子路由

    r.Host("{subdomain:[a-z]+}.example.com")

    3.2 更多的一些其他匹配

    见下面的更多匹配的例子:

    r := mux.NewRouter()

    r.PathPrefix("/products/") //前缀匹配

    r.Methods("GET", "POST") //请求方法匹配

    r.Schemes("https") //schemes

    r.Headers("X-Requested-With", "XMLHttpRequest") //header 匹配

    r.Queries("key", "value") //query的值匹配

    // 用户自定义方法 匹配

    r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {

    return r.ProtoMajor == 0

    })

    把上面的联合起来在一个单独的route里

    r.HandleFunc("/products", ProductsHandler).

    Host("www.example.com").

    Methods("GET").

    Schemes("http")

    3.3 子路由匹配

    Subrouter()可以设置子路由

    r := mux.NewRouter()

    s := r.Host("www.example.com").Subrouter()

    s.HandleFunc("/products/", ProductsHandler)

    s.HandleFunc("/products/{key}", ProductHandler)

    s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

    3.4 多个路由匹配的顺序

    如果有多个路由添加到路由器里面,那么匹配顺序是怎么样?按照添加的先后顺序匹配。比如有2个路由都匹配了,那么优先匹配第一个路由。

    r := mux.NewRouter()

    r.HandleFunc("/specific", specificHandler)

    r.PathPrefix("/").Handler(catchAllHandler)

    4. 设置路由前缀

    PathPrefix()设置路由前缀

    r := mux.NewRouter()

    //PathPrefix() 可以设置路由前缀

    product := r.PathPrefix("/products").HandleFunc("/", ProductsHandler)

    路由前缀一般情况下不会单独使用,而是和子路由结合起来用,实现路由分组

    5. 分组路由

    可以根据前面的子路由和路由前缀的功能,综合运用就可以设置分组路由了

    实例:grouprouter.go

    package main

    import (

    "fmt"

    "github.com/gorilla/mux"

    "net/http"

    )

    //子路由, 分组路由

    func main() {

    r := mux.NewRouter()

    //PathPrefix() 可以设置路由前缀,设置路由前缀为products

    products := r.PathPrefix("/products").Subrouter()

    //"http://localhost:8080/products/", 最后面的斜线一定要,不然路由不正确,页面出现404

    products.HandleFunc("/", ProductsHandler)

    //"http://localhost:8080/products/{key}"

    products.HandleFunc("/{key}", ProductHandler)

    users := r.PathPrefix("/users").Subrouter()

    // "/users"

    users.HandleFunc("/", UsersHandler)

    // "/users/id/参数/name/参数"

    users.HandleFunc("/id/{id}/name/{name}", UserHandler)

    http.ListenAndServe(":8080", r)

    }

    func ProductsHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "%s", "products")

    }

    func ProductHandler(w http.ResponseWriter, r *http.Request) {

    vars := mux.Vars(r) //获取路由的值

    fmt.Fprintf(w, "key: %s", vars["key"])

    }

    func UsersHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, " %s \r\n", "users handler")

    }

    func UserHandler(w http.ResponseWriter, r *http.Request) {

    vars := mux.Vars(r) //获取值

    id := vars["id"]

    name := vars["name"]

    fmt.Fprintf(w, "id: %s, name: %s \r\n", id, name)

    }

    6. 路由中间件

    https://github.com/gorilla/mux#middleware

    Mux middlewares are defined using the de facto standard type: 在mux中路由中间件的定义

    type MiddlewareFunc func(http.Handler) http.Handler

    示例1:middleware1.go

    package main

    import (

    "fmt"

    "net/http"

    "github.com/gorilla/mux"

    )

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/", handler)

    r.Use(loggingMiddleware)

    http.ListenAndServe(":8080", r)

    }

    func loggingMiddleware(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    //Do stuff here

    fmt.Println(r.RequestURI)

    fmt.Fprintf(w, "%s\r\n", r.URL)

    // Call the next handler, which can be another middleware in the chain, or the final handler.

    next.ServeHTTP(w, r)

    })

    }

    func handler(w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("handle middleware"))

    fmt.Println("print handler")

    }

    示例2:middleware2.go

    在来看一个复杂点的例子:

    package main

    import (

    "fmt"

    "net/http"

    "strings"

    "github.com/gorilla/mux"

    )

    type authMiddleware struct {

    tokenUsers map[string]string

    }

    func (amw *authMiddleware) Populate() {

    amw.tokenUsers = make(map[string]string)

    amw.tokenUsers["000"] = "user0"

    amw.tokenUsers["aaa"] = "userA"

    amw.tokenUsers["05ft"] = "randomUser"

    amw.tokenUsers["deadbeef"] = "user0"

    }

    func (amw *authMiddleware) Middleware(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    token := strings.Trim(r.Header.Get("X-Session-Token"), " ")

    if token == "" {

    fmt.Fprintf(w, "token is error \r\n")

    }

    if user, found := amw.tokenUsers[token]; found {

    //we found the token in out map

    fmt.Printf("Authenticated user: %s\n", user)

    fmt.Fprintf(w, "Authenticated user: %s\n", user)

    // Pass down the request to the next middleware (or final handler)

    next.ServeHTTP(w, r)

    } else {

    // Write an error and stop the handler chain

    http.Error(w, "Forbidden", http.StatusForbidden)

    }

    })

    }

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/", handler)

    amw := authMiddleware{}

    amw.Populate()

    r.Use(amw.Middleware)

    http.ListenAndServe(":8080", r)

    }

    func handler(w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("handler"))

    }

    用 insomnia 软件测试,如下图:

    f85a356cf40afdbbdcdf948b9b89e866.png

    X-Session-Token=aaa 返回时正确

    那-Session-Token=aaaa 呢

    f4cce4f5db546d128a53951d922c4e20.png

    返回 403 了

    7. Walking Routes 遍历注册的所有路由

    package main

    import (

    "fmt"

    "net/http"

    "strings"

    "github.com/gorilla/mux"

    )

    func handler(w http.ResponseWriter, r *http.Request) {

    return

    }

    //https://github.com/gorilla/mux#walking-routes

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/", handler)

    r.HandleFunc("/products", handler).Methods("POST")

    r.HandleFunc("/articles", handler).Methods("GET")

    r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")

    r.HandleFunc("/authors", handler).Queries("surname", "{surname}")

    err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {

    pathTemplate, err := route.GetPathTemplate()

    if err == nil {

    fmt.Println("ROUTE:", pathTemplate)

    }

    pathRegexp, err := route.GetPathRegexp()

    if err == nil {

    fmt.Println("Path regexp:", pathRegexp)

    }

    queriesTemplates, err := route.GetQueriesTemplates()

    if err == nil {

    fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))

    }

    queriesRegexps, err := route.GetQueriesRegexp()

    if err == nil {

    fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))

    }

    methods, err := route.GetMethods()

    if err == nil {

    fmt.Println("Methods:", strings.Join(methods, ","))

    }

    fmt.Println()

    return nil

    })

    if err != nil {

    fmt.Println(err)

    }

    http.Handle("/", r)

    http.ListenAndServe(":8080", nil)

    }

    8. 其他示例

    请求方法限制

    demo3.go:

    package main

    import (

    "fmt"

    "github.com/gorilla/mux"

    "net/http"

    )

    // 请求方法的限制, Methods()

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/products", ProductsHandler).Methods("GET", "POST")

    r.Handle("/products/{id}", &ProductsIdHandler{}).Methods("GET")

    http.ListenAndServe(":8080", r)

    }

    func ProductsHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "hello, products! ")

    }

    type ProductsIdHandler struct{}

    func (handler *ProductsIdHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    vars := mux.Vars(r)

    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "products id: %s", vars["id"])

    }

    请求头限制

    在路由定义中可以通过Headers() 方法来限制设置请求头的匹配。

    demo4.go

    package main

    import (

    "fmt"

    "net/http"

    "github.com/gorilla/mux"

    )

    // 请求头的限制,用Headers() 来限制

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/products", func(w http.ResponseWriter, r *http.Request) {

    header := "Request-Limit-Test"

    fmt.Fprintf(w, "contain headers: %s = %s \n", header, r.Header[header])

    }).Headers("Request-Limit-Test", "RequestLimitTest").Methods("POST")

    http.ListenAndServe(":8080", r)

    }

    自定义匹配规

    用 MatcherFunc() 来自定义规则

    示例 demo5.go:**

    package main

    import (

    "fmt"

    "net/http"

    "github.com/gorilla/mux"

    )

    //自定义匹配 MatcherFunc()

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/products/matcher", func(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "FormValue: %s ", r.FormValue("func"))

    }).MatcherFunc(func(req *http.Request, match *mux.RouteMatch) bool {

    b := false

    if req.FormValue("func") == "matcherfunc" {

    b = true

    }

    return b

    })

    http.ListenAndServe(":8080", r)

    }

    命名路由Registered URLs

    namerouter.go

    package main

    import (

    "fmt"

    "github.com/gorilla/mux"

    // "log"

    "net/http"

    )

    // 命名路由 Name(), 获取路由URL, URL()

    func main() {

    r := mux.NewRouter()

    r.HandleFunc("/products/{category}/{id:[0-9]+}", ProductHandler).Name("product")

    //获取路由的URL

    url1, err := r.Get("product").URL()

    fmt.Println(err) //error: mux: number of parameters must be multiple of 2, got [/]

    if err == nil {

    fmt.Println("get URL: \r\n", url1)

    }

    //获取路由的url后,也可以拼装你需要的URL

    url2, err := r.Get("product").URL("category", "tech", "id", "13")

    if err == nil {

    fmt.Println("new url: ", url2) //new url: /products/tech/13

    }

    http.ListenAndServe(":8080", r)

    }

    func ProductHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    vars := mux.Vars(r)

    fmt.Fprintf(w, "url: %s, category: %s, id: %s", r.URL, vars["category"], vars["id"])

    //浏览器: http://localhost:8080/products/id/23

    //output

    //url: /products/id/23, category: id, id: 23

    }

    根据命名的路由来获取路由URLr.Get("product").URL()

    三:参考

    到此这篇关于golang常用库之gorilla/mux-http路由库使用详解的文章就介绍到这了,更多相关gorilla mux-http路由库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    展开全文
  • Android路由跳转——ARouter使用

    千次阅读 2017-10-10 11:18:16
    最近在研究组件化/模块化开发过程中突然遇到跨模块交互瓶颈,(例如A模块想要跳转B模块页面,由于AB模块相互独立并不存在依赖关系,因此使用常规的显式Intent路由是无法实现,而隐式Intent路由虽然可通过指定包名+类...

    前言

    模块化开发过程中首要解决的问题是如何进行跨模块交互,由于模块与模块之间不存在类的依赖关系因此类无法直接使用,在软件开发过程中随着业务不断膨胀,模块化开发就凸显得尤为重要。最近在研究组件化/模块化开发过程中突然遇到跨模块交互瓶颈,(例如A模块想要跳转B模块页面,由于AB模块相互独立并不存在依赖关系,因此使用常规的显式Intent路由是无法实现,而隐式Intent路由虽然可通过指定包名+类名实现但是由于需要对URL集中式管理涉及多人开发弊端暴露无遗,导致协作变得困难)那么有没有更为简洁的方式实现呢?答案是肯定的——ARouter。

    ARouter 是阿里巴巴开源的一款android路由框架,github地址为 https://github.com/alibaba/ARouter

    效果如下:


    ARouter 实现原理

    ARouter在编译期的时候,利用自定义注解完成了页面的自动注册,经过代码编译后,生成了相应的映射文件,初始化会将这些文件加载到内存中去,形成一个路由表,以供后面路由查找跳转之用

    ARouter 功能

    1. 支持直接解析URL进行跳转、参数按类型解析到Bundle,支持Java基本类型(*)
    2. 支持应用内的标准页面跳转,API接近Android原生接口
    3. 支持多模块工程中使用,允许分别打包,包结构符合Android包规范即可(*)
    4. 支持跳转过程中插入自定义拦截逻辑,自定义拦截顺序(*)
    5. 支持服务托管,通过ByName,ByType两种方式获取服务实例,方便面向接口开发与跨模块调用解耦(*)
    6. 映射关系按组分类、多级管理,按需初始化,减少内存占用提高查询效率(*)
    7. 支持用户指定全局降级策略
    8. 支持获取单次跳转结果
    9. 丰富的API和可定制性
    10. 被ARouter管理的页面、拦截器、服务均无需主动注册到ARouter,被动发现
    11. 支持Android N推出的Jack编译链

    ARouter 使用

    这里就通过App 跨模块交互了解一下ARouter基本的页面跳转使用姿势

    • 宿主内部跳转(1,2)
    • 宿主跳转模块(3,4,5,6)
    • 模块跳转宿主(7,8)
    • 模块跳转模块(9,10)

    如下图:


    1 创建测试工程

    • 首先建立宿主工程App 以及对应的MActivity(简称M)、M1Activity(简称M1)、M2Activity(简称M2)


    • 在Project下面的Gradle配置 dependencies 添加如下:

    • 宿主工程中的Gradle中 引用apt插件:


           

    同时添加arouter依赖


    工程如下:


    • 新建模块  ModuleA (简称MA)、ModuleB(简称MB

    • 配置MA与MB Gradle文件,引入apt插件和arouter依赖。


    • 分别创建模块 MA(MA1Activity、MA2Activity) ,MB(MB1Activity、MB2Activity)对应测试文件。

    • MActivity测试入口界面如下:

    2 宿主内部跳转(1,2)

    • M1、M2分别实现 Route注解如下:



    • 宿主 中跳转内部页面 M1,使用系统提供的Intent路由跳转如下:


           现在我们使用ARouter来进行页面跳转如下:(build参数为M1类的Path注解值):


    • 宿主 跳转内部页面 M2 并且携带参数,系统Intent跳转如下:

          使用ARouter进行页面跳转并且携带参数如下:


    ARouter的build参数为跳转的目标页面注解时候的path值。

    以上两种方案效果都是一致的并且ARouter是通过编译时期注解实现路由跳转与系统路由Intent比较并不会存在性能问题,那么既然效果一样ARouter 有点在哪里呢?系统提供的Intent路由需要类直接依赖才可实现,而ARouter则无需类的依赖就可实现页面跳转,下面跨模块跳转更为明显。

    3 宿主跳转模块(3,4,5,6)

    • 首先实现模块MoudleA中的 MA1MA2类的注解(MB1,MB2同样)


    • 编译打包生成目标 aar 文件,拷贝至宿主App的libs目录下同时配置Gradle引入此aar。
    • 宿主 M 使用ARouter起调模块 MA1 则如下:

    • 宿主M 使用ARouter起调模块MA2并携带参数如下:

    可见 此处使用ARouter来进行页面跳转的好处已经显而易见了,宿主 跳转模块MA1MA2并没有存在类的依赖关系。这样就很便利的解决的模块调用问题,有利于模块解耦。

    4 模块跳转宿主(7,8)


    • 模块 MA1 跳转至宿主 M1 页面

    • 模块 MA1 携参跳转至宿主 M2 页面

    5 模块跳转模块(9,10)


    • 模块 MB1 跳转模块 MA1 页面

    • 模块 MB1 携参跳转模块 MA2 页面

    由上可见,使用ARouter进行模块之间页面跳转完全脱离了类的依赖。

    ARouter 基本页面跳转至此已经结束,当前还有文中未提及的 跳转回调类似Android系统提供的 startActivityForResult 与之对应的ARouter提供的方案为

    ARouter.getInstance().build(path).navigation(Context context,int requestCode);

    context——>上下文

    requestCode——> 请求code


    关于ARouter还提供丰富的API像路由拦截,跳转降级等等更多使用请参考官方文档。



    展开全文
  • Android路由框架用法

    2020-11-21 14:30:19
    一、什么是android路由? 主要是映射页面跳转关系,根据路由表将页面请求分发到指定页面。 二、android路由使用场景 App接收到一个通知,点击通知打开App的某个页面 浏览器App中点击某个链接打开App的某个页面 ...

    一、什么是android路由?

    主要是映射页面跳转关系,根据路由表页面请求分发到指定页面。

    二、android路由使用场景

    1. App接收到一个通知,点击通知打开App的某个页面
    2. 浏览器App中点击某个链接打开App的某个页面
    3. 运营活动需求,动态把原生的页面替换成H5页面
    4. 打开页面需要某些条件,先验证完条件,再去打开那个页面
    5. 不合法的打开App的页面被屏蔽掉
    6. H5打开链接在所有平台都一样,方便统一跳转
    7. 打开某个APP,如果APP存在就直接打开,不存在就去下载页面下载

    三、为什么需要路由框架?

    Android原生系统已经给我们提供了AndroidManifest去管理页面跳转,比如startActivity,为什么还需要使用路由框架呢?我们来简单分析下路由框架存在的意义:

    1. 显示Intent:项目庞大以后,类依赖耦合太大,不适合组件化拆分
    2. 隐式Intent:协作开发困难,调用的时候不知道调什么参数
    3. 每个注册了Scheme的Activity都可以直接打开,有安全风险
    4. AndroidMainfest集中式管理比较臃肿
    5. 无法动态修改路由,如果页面出错,无法动态降级
    6. 无法动态拦截跳转,例如未登录的情况下,打开登录页面,登录成功后接着打开刚才想打开的页面
    7. H5、Android、iOS地址不一样,不利于统一跳转
    8. 在一些复杂的业务场景下(比如电商),灵活性比较强,很多功能都是运营人员动态配置的,比如下发一个活动页面,我们事先并不知道具体的目标页面,但如果事先做了约定,提前做好页面映射,便可以自由配置。
    9. 简化代码,数行跳转代码精简成一行代码,这个大家应该都很容易理解,无非就是对代码块的封装。

    四、选择怎么样的路由框架比较好?

    路由说到底还是为了解决开发者遇到的各种奇葩需求,选择路由框架要求使用简单、侵入性低、维护方便是首要条件,不影响你原来的代码,写入代码越少越好,这里推荐使用ARouter路由框架。

    ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,一个用于帮助 Android App 进行组件化改造的框架,支持模块间的路由、通信、解耦,提倡的是简单且够用。

    GitHub地址:https://github.com/alibaba/ARouter

    ARouter的优势:

    1. 支持直接解析标准URL进行跳转,并自动注入参数到目标页面中
    2. 支持多模块工程使用
    3. 支持添加多个拦截器,自定义拦截顺序
    4. 支持依赖注入,可单独作为依赖注入框架使用
    5. 支持InstantRun
    6. 支持MultiDex(Google方案)
    7. 映射关系按组分类、多级管理,按需初始化
    8. 支持用户指定全局降级与局部降级策略
    9. 页面、拦截器、服务等组件均自动注册到框架
    10. 支持多种方式配置转场动画
    11. 支持获取Fragment
    12. 完全支持Kotlin以及混编(配置见文末 其他#5)
    13. 支持第三方 App 加固(使用 arouter-register 实现自动注册)
    14. 支持生成路由文档
    15. 提供 IDE 插件便捷的关联路径和目标类
    16. 支持增量编译(开启文档生成后无法增量编译)

    ARouter的典型应用:

    1. 从外部URL映射到内部页面,以及参数传递与解析
    2. 跨模块页面跳转,模块间解耦
    3. 拦截跳转过程,处理登陆、埋点等逻辑
    4. 跨模块API调用,通过控制反转来做组件解耦

    五、ARouter的使用示例:

    第一步:ARouter配置(添加依赖,引入类库)

    打开build.gradle文件,在dependencies {}配置项里引入ARouter的远程类库(不懂的可以参考github上的官方说明),代码如下:

    android {
        defaultConfig {
           
             //前面的代码省略...
            
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName()]
                }
            }
        }
    }
    
    dependencies {
        implementation 'com.alibaba:arouter-api:1.5.1'
        annotationProcessor 'com.alibaba:arouter-compiler:1.5.1'
    }

     注意:

    1、如果是组件化开发,那么所有的module组件(包括主项目和library项目的build.gradle都要添加如上的依赖配置,如果只是加在公共的common组件里,是完全不起作用的。

    2、api 的版本和 compiler 的版本号需要用最新的,最新的版本在官方的Github上可以看到,如下图:

    第二步:添加ARouter路由注解(可选)

    **
     * 在支持路由的页面上添加注解(必选)
     * 注意:这里的路径需至少需要有两级,/xx/xx
     */
    @Route(path = "/test/RouteActivity")
    public class RouteDemoActivity extends AppCompatActivity {
        //省略这里的代码....
    }

    上面的代码就是在目标Activity类上面声明Route path 注解,以此对应,跳转如果不对应路径,框架会Toast说路径不匹配。

    第三步:ARouter初始化

    方建议我们在Application里面进行ARouter初始化,因此需要创建一个自定义的Application,看下面的步骤:

    1、在Activity同级包里,创建一个新的类RouteApplication.java继承Application,代码如下:

    import android.app.Application;
    
    import com.alibaba.android.arouter.launcher.ARouter;
    
    /**
     * @author 安阳 QQ:15577969
     * @version 1.0
     * @team 美奇软件开发工作室
     * @date 2020/11/14 14:56
     */
    public class RouteApplication extends Application {
        //ARouter调用开关
        private boolean isDebugARouter=true;
    
        @Override
        public void onCreate() {
            super.onCreate();
            if (isDebugARouter) {
                // 打印日志
                ARouter.openLog();
                // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
                ARouter.openDebug();
            }
            ARouter.init(this);
        }
    }
    

    2、在AndroidManifest.xml清单配置文件,<application>中加入android:name="RouteApplication"

    <application
        android:name="RouteApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    第四步:发起路由操作

     //应用内简单的跳转(通过URL跳转在'进阶用法'中)
     ARouter.getInstance().build("/test/RouteActivity").navigation();

    六、监听路由过程

     ARouter.getInstance().build("/test/RouteActivity").navigation(this, new NavCallback() {
                @Override
                public void onFound(Postcard postcard) {
                    Log.e("监听路由过程", "onArrival: 找到了路由");
                }
    
                @Override
                public void onLost(Postcard postcard) {
                    Log.e("监听路由过程", "onArrival: 找不到路由");
                }
    
                @Override
                public void onArrival(Postcard postcard) {
                    Log.e("监听路由过程", "onArrival: 路由跳转完成");
                }
    
                @Override
                public void onInterrupt(Postcard postcard) {
                    Log.e("监听路由过程", "onArrival: 路由被拦截了");
                }
    });

    七、发起路由并且传递参数

    // 跳转并携带参数
    ARouter.getInstance().build("/test/RouteActivity")
                    .withLong("id", 1)
                    .withString("name", "张三")
                    .withObject("obj", this)
                    .navigation();

    ARouter 提供了大量的参数类型,如下所示:

    //基础类型
    .withString( String key, String value )
    .withBoolean( String key, boolean value)
    .withChar( String key, char value )
    .withShort( String key, short value)
    .withInt( String key, int value)
    .withLong( String key, long value)
    .withDouble( String key, double value)
    .withByte( String key, byte value)
    .withFloat( String key, float value)
    .withCharSequence( String key,  CharSequence value)
    
    //数组类型
    .withParcelableArrayList( String key, ArrayList<? extends Parcelable > value)
    .withStringArrayList( String key,  ArrayList<String> value)
    .withIntegerArrayList( String key, ArrayList<Integer> value)
    .withSparseParcelableArray( String key, SparseArray<? extends Parcelable> value)
    .withCharSequenceArrayList( String key, ArrayList<CharSequence> value)
    .withShortArray( String key,  short[] value)
    .withCharArray( String key, char[] value)
    .withFloatArray( String key, float[] value)
    .withCharSequenceArray( String key,  CharSequence[] value)
    
    //Bundle 类型
    .with( Bundle bundle )
    
    //Activity 跳转动画
    .withTransition(int enterAnim, int exitAnim)
    
    //其他类型
    .withParcelable( String key, Parcelable value)
    .withParcelableArray( String key,  Parcelable[] value)
    .withSerializable( String key, Serializable value)
    .withByteArray( String key, byte[] value)
    .withTransition(int enterAnim, int exitAnim)

    八、路由分组

    什么是路由分组?

    ARouter框架是分组管理,按需加载。在编译期框架扫描了所有的注册页面/服务/字段/拦截器等,那么很明显运行期不可能一股脑全部加载进来,这样就太不和谐了。所以就分组来管理,ARouter在初始化的时候只会一次性地加载所有的root结点,而不会加载任何一个Group结点,这样就会极大地降低初始化时加载结点的数量。比如某些Activity分成一组,组名就叫demo,然后在第一次需要加载组内的某个页面时再将demo这个组加载进来。 

    @Route(path = "/test/RouteActivity")

    上面这行代码,就是我们前面添加的路由注释,最前面的demo就是路由分组。我们还可以在监控路由过程里,获取所在的分组,代码如下:

     ARouter.getInstance().build("/test/RouteActivity").navigation(this, new NavCallback() {
                @Override
                public void onArrival(Postcard postcard) {
                    String group = postcard.getGroup();
                    Log.e("监听路由过程", "当前路由分组是: " + group);
                }
    
    });

    运行结果如下:

    九、自定义路由分组

     1、在原来的注解上添加group字段

    **
     * 添加路由和分组
     */
    @Route(path = "/test/RouteActivity", group = "testGroup")
    public class RouteDemoActivity extends AppCompatActivity {
        //省略这里的代码....
    }

    2、发起路由时,第二个参数填写路由的分组

    build(String path, String group)

    具体示例代码如下:

     // 应用内简单的跳转(通过URL跳转在'进阶用法'中)
    ARouter.getInstance().build("/test/RouteActivity","testGroup").navigation();

    3、添加自定义分组后,运行结果如下:

    十、Fragment路由

    创建 Fragment 类,并且添加路由注解,如下:

    /**
     * 添加Fragment碎片路由
     */
    @Route(path = "/test/ModuleFragment")
    public class ModuleCFragment extends Fragment {
        //省略这里的代码....
    }

    然后我们可以通过路由,获取Fragment实例:

    //通过路由,获取Fragment实例
    Fragment moduleFragment = (Fragment) ARouter.getInstance().build( "/test/ModuleFragment" ).navigation();

    十一、android和html交互:通过URL跳转(进阶用法)

    先来看一下web的URL链接跳转流程图:

    1、创建一个URL中间跳转页,可以在公共common组件里创建一个URLReceiveActivity活动,具体代码如下:

    /**
     * URL中间跳转页
     * 原理:新建一个Activity用于监听Scheme事件,之后直接把url传递给ARouter即可
     */
    public class URLReceiveActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_urlreceive);
            //对URI数据进行分发
            Uri uri = getIntent().getData();
            ARouter.getInstance().build(uri).navigation();
            finish();
        }
    }

    2、URLReceiveActivity需要在AndroidManifest.xml清单文件里,添加如下注册:

    <activity android:name=".URLReceiveActivity">
                <intent-filter>
                    <data
                        android:host="m.zy13.net"
                        android:scheme="arouter" />
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                </intent-filter>
    </activity>

    注意:这里面的 host 、scheme 字段很重要。点击 url 会根据这两个字段调起本地的Activity 。

    3、将android studio目录模式切换至Project,然后在main目录下创建一个assets目录:

    4、在 assets目录下创建一个demo.html文件,编写如下HTML代码:

    <!doctype html>
    <html>
    <head>
        <!-- 设置当前HTML文件的字符编码 -->
        <meta charset="utf-8">
        <!-- 设置浏览器的兼容模式版本 (让IE使用最新的渲染引擎工作) -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <!-- 声明当前网页在移动端浏览器中展示的相关设置 -->
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    </head>
    <body>
    <h2>1、URL普通跳转</h2>
    <p>
        <a href="arouter://m.zy13.net/test/RouteActivity">URL普通跳转</a>
    </p>
    <h2>2、URL普通跳转携带参数</h2>
    <p>
        <a href="arouter://m.zy13.net/test/RouteActivity?name=xiao7&age=18">URL普通跳转携带参数</a>
    </p>
    </body>
    </html>

    注明: a标签里面的arouter://m.zy13.net分别代表着schemehost,/demo/RouteActivity就是目标Activity的注解。

    5、在需要与html交互的活动页面xml布局里,添加WebView控件:

        <WebView
            android:id="@+id/webview"
            android:layout_marginTop="50dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

    6、然后在Activity活动的onCreate()里加载html页面,如下:

    private WebView contentWebView = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 从assets目录加载html文件
            contentWebView = (WebView) findViewById(R.id.webview);
            contentWebView.loadUrl("file:///android_asset/demo.html");
    }

    在实际开发中,通常是直接调用网址链接与html进行交互的,这里为了简化,我们直接加载了html文件,效果如下:

    7、如果需要接收 UR 中的参数,需要在Activity中调用自动注入初始化的方法,代码如下:

    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.alibaba.android.arouter.facade.annotation.Autowired;
    import com.alibaba.android.arouter.facade.annotation.Route;
    import com.alibaba.android.arouter.launcher.ARouter;
    
    /**
     * 在支持路由的页面上添加注解(必选)
     * 注意:这里的路径需至少需要有两级,/xx/xx
     */
    @Route(path = "/test/RouteActivity")
    public class RouteDemoActivity extends AppCompatActivity {
        private TextView textView;
    
        //为每一个参数声明一个字段,并使用@Autowired标注
        @Autowired
        String name;
    
        // 通过name来映射URL中的不同参数
        @Autowired(name = "age")
        int age;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //自动注入初始化,ARouter会自动对字段进行赋值,无需主动获取
            ARouter.getInstance().inject(this);
            setContentView(R.layout.activity_route_demo);
            //文本
            textView = (TextView) findViewById(R.id.urlTextView);
    
            textView.setText("URL参数是: " + "name: " + name + "  age: " + age);
    
        }
    }
    

    8、如果不使用自动注入,那么可以不写ARouter.getInstance().inject(this),但是需要取值的字段仍然需要标上 @Autowired 注解,因为 只有标上@Autowired注解之后,ARouter才能知道以哪一种数据类型提取URL中的参数并放入Intent中,这样才能在intent中获取到对应的参数,具体的代码如下:

    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.alibaba.android.arouter.facade.annotation.Autowired;
    import com.alibaba.android.arouter.facade.annotation.Route;
    import com.alibaba.android.arouter.launcher.ARouter;
    
    /**
     * 在支持路由的页面上添加注解(必选)
     * 注意:这里的路径需至少需要有两级,/xx/xx
     */
    @Route(path = "/test/RouteActivity")
    public class RouteDemoActivity extends AppCompatActivity {
        private TextView textView;
    
        //为每一个参数声明一个字段,并使用@Autowired标注
        @Autowired
        String name;
    
        // 通过name来映射URL中的不同参数
        @Autowired(name = "age")
        int age;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_route_demo);
            //文本
            textView = (TextView) findViewById(R.id.urlTextView);
    
             /**
             * 解析URL参数,手动获取
             */
            Bundle bundle = getIntent().getExtras();
            name = bundle.getString("name");
            age = bundle.getInt("age");
    
            textView.setText("URL参数是: " + "name: " + name + "  age: " + age);
    
        }
    }
    

    获取URL参数效果如下:

    十二、对外暴露接口服务 

    这里所指的服务不是Android四大组件中的Service,而是接口开发的概念,就是将一部分功能和组件封装起来成为接口,以接口的形式对外提供能力,我们可以将需要对外提供的功能作为一个服务,而服务的实现就是具体的业务功能。

    1、先自定义一个接口 IService 并且继承 IProvider ,IService 接口里面有一个 getData() 方法,具体代码如下:

    public interface IService extends IProvider {
        void getData(Context context );
    }

    2、然后定义一个 IService 的实现类 MyService 并且添加注解,代码如下:

    import android.content.Context;
    import android.widget.Toast;
    
    import com.alibaba.android.arouter.facade.annotation.Route;
    
    import net.zy13.module.common.service.IService;
    
    /**
     * @author 安阳 QQ:15577969
     * @version 1.0
     * @team 美奇软件开发工作室
     * @date 2020/11/21 14:14
     */
    @Route(path = "/service/demo", name = "测试服务")
    public class MyService implements IService {
        @Override
        public void demo(Context context) {
            Toast.makeText(  context , "这是一个对外暴露的接口服务!", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void init(Context context) {
    
        }
    }
    

    十三、发现接口服务

    1、定义服务对象, 通过@Autowired注解依赖注入接口服务,我们不需要知道接口的具体实现类,如下:

    //使用依赖注入的方式发现服务,通过注解标注字段,即可使用,无需主动获取
    @Autowired(name = "/service/demo")
    IService service;
    
    Autowired注解中标注name之后,将会使用byName的方式注入对应的字段,不设置name属性,会默认使用byType的方式发现服务(注意:当同一接口有多个实现的时候,必须使用byName的方式发现服务)

    2、然后添加注解初始化,自动赋值

    ARouter.getInstance().inject(this);

    3、这样就可以调用 service接口服务里面的 demo() 方法了

    service.demo(this);

    效果如下: 

    展开全文
  • 不清楚你是不是知道,咱们中国有相当大的一部分软件公司,他们的软件开发团队都小的可怜,甚至只有1-3个人,连一个项目小组都算不上,而这样的团队却要承担一个软件公司所有的软件开发任务,在软件上线和开发的关键...
  • 刚开始做完第一个应用,开始重构我的代码。没有java编程基础,还是初学,希望各位路过不要见笑。...1.首先定义一个页面跳转辅助类 IntentHepler、并在AddRoutingRule()方法中添加我想要的路由规则 public...
  • HCNA认证包括但不限于:网络基础知识,流行网络的基本连接方法,基本的网络建造,基本的网络故障排除,华为路由交换设备的安装和调试。 通过HCNA认证,将证明您对中小型网络有初步的了解,了解中小型网络的通用技术...
  • 虚拟wifi 网络 支持安卓 很多虚拟wifi软件不支持安卓系统 这个软件可以
  • 前言上篇我们介绍了 APT 在 Router 框架中的使用,通过注解处理器搜集路由信息,本篇我们来聊一下 Router 的运行机制。为什么要用拦截器?我们先看一下路由的使用场景服务端下发一个链接,首先我们需要判断这个链接...
  • 目前Android APP开发主流语言就是Java语言,Java语言最大的特性就是提高了软件的交互可能性,可以说安卓手机几乎所有应用程序都是利用Java语言来进行编写的。使用Java语言开发的软件的程序库、数据库、
  • A lightweight, simple, smart and powerful Android routing library. Getting started Setting up the dependency Add to your project build.gradle file: dependencies { implementation 'zlc.season:rxrouter:...
  • 手机移动端网络路由跟踪探测方式在使用移动网络访问服务器中的服务时,如果网络存在异常,可以通过以下方式进行定位:获取...根据移动端的系统不同,iPhone iOS 或 Android,获取方式也不同。iPhone iOS 路由跟踪...
  • 一款非常实用的无线路由器相关密钥破解工具。进入软件后需要简单的设置一下,可能需要获取dictionaries(字典)。 当应用界面显示的无线信号左侧条栏显示为绿色说明,可以获取相关无限路由器密钥。
  • Android组件化方案—阿里路由ARouter的使用。
  • 本次分享将主要围绕以下几个方面:一、为什么需要路由框架二、ARouter的技术方案三、使用ARouter的最佳实践四、未来开发计划一、为什么需要路由框架原生的路由方案存在的问题首先谈一谈原生的路由方案存在的问题以及...
  • 马卡尔 Android VoIP 应用程序,可通过本地 wifi 网络进行语音通话。 此应用程序需要服务器端 java 软件来在客户端之间路由消息和语音通话。
  • Android 组件化之路 路由设计

    千次阅读 2017-08-11 16:10:52
    基于公司业务发展,公司的APP需求不断增加,应用也略显“臃肿”。...组件化: 基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件。区别: 模块化和组件化本质思想是一样的,都是“大
  • 阿里ARouter路由实现Android模块化开发

    千次阅读 2018-04-23 22:54:08
    随着移动平台的不断发展,移动平台上的软件慢慢走向复杂化,体积也变得臃肿庞大,为了降低大型软件复杂性和耦合度,同时也为了适应模块重用、多团队并行开发测试等等需求,模块化在 Android 平台上变得势在必行。...
  • 不是安卓不行了,是你跟不上了 我的很多读者都在反馈说,现在一个岗位可以收到的简历数,是前几年的几倍。我们必须承认,僧多粥少就是 Android 行业的现状,别说初中级工程师,就是高级工程师也是一抓一大把。企业招...
  • 海哥在N年前也是觉得这样很痛苦本着造福人类的想法,我决定重写TFTP这个软件,然后保持原先的风格,然后简化刷机过程BCM路由智能刷机教程:1、请把本机的IP设置为192.168.1.x段的,x为2-254的任意数字,...
  • 手机客户端软件:分别在小米手机和iphone(4S)上安装了“小米路由软件,都是小米官方的软件,不得不说小米是做安卓出身的,在安卓下的软件做的确实挺好,但是IOS就一般了。软件在小米手机上一切正常,备份照片也...
  • 阿里云资深开发工程师,主要从事Android端应用开发,负责阿里云App的Android端架构设计、中间件开发;阿里云App服务于阿里云官网用户,用户可以便捷的在移动端管控云上资源,了解云栖社区资讯等。 视频介绍 ...
  • C++模拟安卓中ARouter实现了页面路由功能 1、所有页面均在ViewRouter中进行创建与销毁 2、ViewRouter创建一个视图路由框架ViewFrame 3、ViewFrame负责页面的隐藏与显示 4、ViewRouter仅维护整屏页面跳转的页面...
  • 在本次在线技术峰会上,阿里云资深开发工程师刘志龙分享了Android平台页面路由框架ARouter的技术方案、解决的问题以及在实际场景中的最佳实践。 演讲嘉宾介绍: 刘志龙(花名正纬),阿里云资深开发工程师,
  • 路由体验 篇一: 100块钱还要啥自行车,软路由初体验2019-12-19 19:42:0042点赞190收藏68评论可能是在论坛泡久了。总有软路由的拥趸在述说着他的强大,弄的我心痒痒的。很想搞一台的试试水。在咸鱼里一直泡着,...
  • 用户一旦下载安装携带该木马的恶意软件,它就会篡改用户的无线路由器DNS设置,劫持用户的网络流量。 除了伪装成百度的安卓客户端,该木马还能伪装成一个用于共享Wi-Fi网络详细信息的中文应用程序,诱导普通用户下载...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,553
精华内容 4,621
关键字:

安卓路由软件