Android开发笔记--ARouter使用

          ARouter 是阿里开源的一个优秀的路由框架,用在Android平台中对页面,服务提供路由功能的中间件。中间件这个概念之前是用在Web端,它是一种独立的服务程序,能够实现不同技术间的资源共享,管理计算资源和网络通信。

          为什么Android中要用到其他(第三方)路由,默认系统已经提供路由如StartActivity?因为在一些复杂的,灵活性比较强的业务下(比如金融,电商),很多功能都是动态配置的,比如下发一个新的会员策略,活动页面等,事先时不知道具体的目标页面,但如果事先做了约定,提前做好页面映射,就可以动态配置。 其次,随着业务的增长,客户端的代码业务越来越大,会引起协作开发问题,资源共用问题,这时App大多会向组件化,插件化发展,而它们的前提就是解耦,解除页面之间的依赖关系。 简单来看一下ARouter的使用,代码如下:

1 添加依赖:

android {}
kapt {
    arguments {
        arg("AROUTER_MODULE_NAME", project.getName())
    }
}
dependencies {
    implementation 'com.alibaba:arouter-api:1.4.0'
    kapt 'com.alibaba:arouter-compiler:1.2.1'
}

2 Application初始化

xxxApplication
override fun onCreate() {
        super.onCreate()
        // 打印日志
        ARouter.openLog()
        ARouter.openDebug()
        ARouter.init(this)
    }

3 添加注解

方式一 启动Activity

 findViewById<Button>(R.id.main_btn).setOnClickListener{
            ARouter.getInstance().build("/com/activity/ResultActivity").navigation()
        }


目标Activity:

@Route(path = "/com/activity/ResultActivity")
class ResultActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)
    }
}
方式二 通过Fragment启动Activity,并且回传参数

MainActivity

activity_main.xml

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

<FrameLayout
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
</LinearLayout>
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val fragment = ARouter.getInstance().build("/com/fragment/kotlin").navigation() as Fragment
        supportFragmentManager.beginTransaction().replace(R.id.root, fragment).commit()

    }
}
@Route(path = "/com/fragment/result")
class ResultFragment : Fragment() {
    var textView: TextView? = null ;

    companion object {
        const val REQUEST_CODE = 101
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        val root = inflater.inflate(R.layout.fragment_result, container, false)
        textView = root.findViewById<TextView>(R.id.fragment_text)
        root.findViewById<Button>(R.id.btn).setOnClickListener {
            FragmentResultRouter
                .build(this@ResultFragment, "/com/activity/ResultActivity")
                .navigation(REQUEST_CODE)
        }

        return root
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == Constants.REQUEST_CODE) {
            val result = data!!.getStringExtra("data")
            println("receive====ResultFragment 结果 : $result")
            textView?.setText(result)
        }
    }

}
@Route(path = "/com/activity/ResultActivity")
class ResultActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)
    }

    override fun finish() {

        val intent = Intent()
        intent.putExtra("data", "world")
        setResult(Activity.RESULT_OK, intent)

        super.finish()
    }
}
class FragmentResultRouter private constructor(fragment: Fragment) {

    companion object {
        private val router = ARouter.getInstance()
        private var mHandler: Handler = Handler(Looper.getMainLooper())

        fun build(fragment: Fragment, path: String): FragmentResultRouter {
            val fragmentRouter = FragmentResultRouter(fragment)
            fragmentRouter.postcard = router.build(path)
            return fragmentRouter
        }

        fun build(fragment: Fragment, uri: Uri): FragmentResultRouter {
            val fragmentRouter = FragmentResultRouter(fragment)
            fragmentRouter.postcard = router.build(uri)
            return fragmentRouter
        }
    }

    private var fragment: Fragment = fragment
    private lateinit var postcard: Postcard

    fun setTag(tag: Any): FragmentResultRouter {
        postcard.tag = tag
        return this
    }

    fun navigation(requestCode: Int) {
        navigation(requestCode, null)
    }

    fun navigation(requestCode: Int, callback: NavigationCallback?) {
        try {
            LogisticsCenter.completion(postcard)
        } catch (e: NoRouteFoundException) {
            if (null != callback) {
                callback.onLost(postcard)
            } else {
                val degradeService = ARouter.getInstance().navigation(DegradeService::class.java)
                degradeService?.onLost(fragment.context, postcard)
            }
            return
        }
        callback?.onFound(postcard)
        if (!postcard.isGreenChannel) {
            val interceptorService = ARouter.getInstance()
                    .build("/arouter/service/interceptor")
                    .navigation() as InterceptorService
            interceptorService.doInterceptions(postcard, object : InterceptorCallback {

                override fun onContinue(postcard: Postcard) {
                    internalNavigation(requestCode, callback)
                }

                override fun onInterrupt(exception: Throwable) {
                    callback?.onInterrupt(postcard)
                }
            })
        } else {
            internalNavigation(requestCode, callback)
        }
    }

    private fun internalNavigation(requestCode: Int, callback: NavigationCallback?) {
        val intent = Intent(fragment.activity, postcard.destination)
        intent.putExtras(postcard.extras)
        val flags = postcard.flags
        if (-1 != flags) {
            intent.flags = flags
        }
        // Set Actions
        val action = postcard.action
        if (!TextUtils.isEmpty(action)) {
            intent.action = action
        }
        // Navigation in main looper.
        if (Looper.getMainLooper().thread != Thread.currentThread()) {
            mHandler.post {
                fragment.startActivityForResult(intent, requestCode, postcard.optionsBundle)
                if (-1 != postcard.enterAnim && -1 != postcard.exitAnim) {    // Old version.
                    fragment.activity!!.overridePendingTransition(postcard.enterAnim, postcard.exitAnim)
                }
            }
        } else {
            fragment.startActivityForResult(intent, requestCode, postcard.optionsBundle)
            if (-1 != postcard.enterAnim && -1 != postcard.exitAnim) {    // Old version.
                fragment.activity!!.overridePendingTransition(postcard.enterAnim, postcard.exitAnim)
            }
        }

        callback?.onArrival(postcard)
    }

    fun with(bundle: Bundle?): FragmentResultRouter {
        postcard.with(bundle)
        return this
    }

}

简单总结一下ARouter特点:

  1 直接解析URL路由,解析参数并赋值到对应目标字段的页面中。
  2 支持多模块项目,实现跨团队开发。
  3 支持InstantRun,类似于代码的日更新,面向的是开发过程,这样可以减少开发和编译的次数,可以将代码修改即时地同步APK中,从而可以大规模降低开发复杂度。
  4 允许自定义拦截器,ARouter是支持拦截器,而拦截器是AOP实现,可以自定义多个拦截器解决一些面向行为编程上出现的问题。
  5 可以提供loC容器,控制反转。
  6 映射关系自动注册,在页面不是很多的小型APP上面,自动注册并不会体现出太大优势,但是对于大型APP而言,可能页面数量已经达到的几十个或者数百个,在这样的情况下,自动注册就显得非常重要了,因为不可能将每一个页面都通过代码的方式进行注册。  
  7 灵活的降级策略,ARouter可以提供多种降级策略给用户,原生的路由方案如StartActivity,处理无法灵活降级问题,一旦失败就会抛出运营级异常;

官方地址:ARouter

猜你喜欢

转载自blog.csdn.net/ljt2724960661/article/details/121061367