当前位置: 首页 > news >正文

西峰住房和城乡建设局网站哪些平台可以做推广

西峰住房和城乡建设局网站,哪些平台可以做推广,做网站c 和java那个好,创意设计绘画作品一、简介 众所周知,在日常开发中,随着项目业务越来越复杂,项目中的代码量也越来越多,如果维护、扩展、解耦等成了一个非常头疼问题,随之孕育而生的诸如插件化、组件化、模块化等热门技术。 而其中组件化中一项的难点&…

一、简介

众所周知,在日常开发中,随着项目业务越来越复杂,项目中的代码量也越来越多,如果维护、扩展、解耦等成了一个非常头疼问题,随之孕育而生的诸如插件化、组件化、模块化等热门技术。 而其中组件化中一项的难点,就是实现各个组件之间的通讯,我们通常解决方案采用路由中间件,来实现页面之间跳转关系。 ARouter 是阿里开源路由框架,常被用于组件之间、模块之间的跳转,由于是国人团队开发的,所以你懂的,中文文档非常详细。

二、入门

2.1.添加依赖

android {defaultConfig {...javaCompileOptions {annotationProcessorOptions {arguments = [AROUTER_MODULE_NAME: project.getName()]}}}
}dependencies {api'com.alibaba:arouter-api:1.5.0'annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
}

2.2.初始化

在 Application 中初始化

if (BuildConfig.DEBUG) {ARouter.openLog()     // 打印日志ARouter.openDebug()   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(this);

2.3.添加注解

@Route(path = "/main/main_main")
public class MainActivity extend BaseActivity {...
}

2.4.发起路由

// 1.应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/main/main_main").navigation();// 2.跳转并携带参数
ARouter.getInstance().build("/main/main_main").withLong("id", 10086L).withString("name", "Test").navigation();

三、原理解析

在原理解析之前,我们先了解 ARouter 使用关键技术-APT(Annotation Processing Tool),它是 javac 的一个工具,中文译名为编译时注解处理器,说白了,APT 用来编译时,扫描和处理注解,获取注解和被注解类等相关信息,拿到这些信息之后,自动生成一些代码,核心是 AbstractProcessor 这个类,APT 运用非常广泛,诸如 ButterKnife、EventBus、Dagger2 等使用运用到了 APT,ARouter 也不例外。运用 APT 技术我们可以自己写一些注解处理器,例如处理网络、打印出错信息等。

3.1 分析

我们来看看 ARouter 初始化

//1.初始化
ARouter.init(application)//2.ARouter#init
public static void init(Application application) {if (!hasInit) {logger = _ARouter.logger;_ARouter.logger.info(Consts.TAG, "ARouter init start.");//委托给_ARouter去初始化hasInit = _ARouter.init(application);if (hasInit) {_ARouter.afterInit();}//初始化之后调用afterInit_ARouter.logger.info(Consts.TAG, "ARouter init over.");}}

从上面我们可以看到 ARouter 采用门面模式,实际上委托给 *ARouter 处理,*ARouter 是整个框架的路由中心控制器,负责处理控制整个路由的流程。接下来,我们看看 _ARouter 初始化化。

protected static synchronized boolean init(Application application) {mContext = application;//调用 LogisticsCenter 的初始化LogisticsCenter.init(mContext, executor);logger.info(Consts.TAG, "ARouter init success!");hasInit = true;mHandler = new Handler(Looper.getMainLooper());return true;
}//LogisticsCenter#init
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {mContext = context;executor = tpe;try {long startInit = System.currentTimeMillis();loadRouterMap();if (registerByPlugin) {logger.info(TAG, "Load router map by arouter-auto-register plugin.");} else {Set<String> routerMap;//1.如果是debug模式,或者有更新if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {logger.info(TAG, "Run with debug mode or new install, rebuild router map.");//1.扫描包,获取ROUTE_ROOT_PAKCAGE(com.alibaba.android.arouter.routes)包下的类routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);if (!routerMap.isEmpty()) {context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();}PackageUtils.updateVersion(context);    // Save new version name when router map update finishes.} else {logger.info(TAG, "Load router map from cache.");//2.获取本地缓存routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));}logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost " + (System.currentTimeMillis() - startInit) + " ms.");startInit = System.currentTimeMillis();for (String className : routerMap) {//3.将 IRouteRoot,IRouteGroup和IProviderGroup的实现类,//通过注解生成,并且加载 Warehouse(数据仓库)// Warehouse:数据仓库,存储路由配置信息和具体生成的IProvider对象if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {//1.加载 IRouteRoot,每个moudle下都会生成一个该类型的实现类,//通过module名来区分的,作用是将每个module下所有的分组按照组名//和对应分组的实现类(IRouteGroup接口的实现类)的 Class 对象做一个映射,//然后保存在一个全局的 groupIndex 的 map 表中。((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {//2.加载 IInterceptorGroup 作用是将各个module下的  自定义的i nterceptor 按照优先级和 interceptor的       // Class 对象做一个映射,然后保存在一个全局的 interceptorIndex 的 map 表中。((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {//3.加载 IProviderGroup 该类的作用的是将项目中自定义的提供序//列化功能的类的相关信息以RouteMeta 类的对象保存在全局的providerIndex的map表中((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);}}}logger.info(TAG, "Load root element finished, cost " + (System.currentTimeMillis() - startInit) + " ms.");if (Warehouse.groupsIndex.size() == 0) {logger.error(TAG, "No mapping files were found, check your configuration please!");}if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "LogisticsCenter has already been loaded, GroupIndex[%d], InterceptorIndex[%d], ProviderIndex[%d]", Warehouse.groupsIndex.size(), Warehouse.interceptorsIndex.size(), Warehouse.providersIndex.size()));}} catch (Exception e) {throw new HandlerException(TAG + "ARouter init logistics center exception! [" + e.getMessage() + "]");}}

从上面代码我们可以看到调用 LogisticsCenter,后勤中心主要完成两件事

  • 获取到 com.alibaba.android.arouter.routes 包下的所有 class 文件类名

  • 根据找到的类名去加载相关的实例到Warehouse中,com.alibaba.android.arouter.routes 包下面的 class 是注解解析器自动生成,主要 IRouteRoot,IRouteGroup 和 IProviderGroup 的实现类,当我们使用 @Route 注解某个类时,会将这个类的信息注入的到自动生成的上述实现类中。 接下来调用 afterInit()。

//_ARouter#afterInit
static void afterInit() {// 调用 Postcard#build 方法,获取 InterceptorService 拦截服务控制器interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();}//build 方法实际上,将 path 和 group 信息封装到 Postcard,生成一个要跳转的信息表protected Postcard build(String path) {if (TextUtils.isEmpty(path)) {throw new HandlerException(Consts.TAG + "Parameter is invalid!");} else {//生成具体实例PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);if (null != pService) {path = pService.forString(path);}return build(path, extractGroup(path));}}//Postcard#navigation 这个方法实现了跳转,我们点进去会发现,最后调用 _ARouter#navigation
//_ARouter#navigation
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {// Pretreatment failed, navigation canceled.return null;}try {//1.调用 LogisticsCenter#completion 的方法LogisticsCenter.completion(postcard);......//不是绿色通道,通过拦截控制器依次调用不同拦截器处理信息  if (!postcard.isGreenChannel()) {  //每个拦截器的拦截方法调用都是在子线程中执行的interceptorService.doInterceptions(postcard, new InterceptorCallback() {@Overridepublic void onContinue(Postcard postcard) {_navigation(context, postcard, requestCode, callback);}@Overridepublic void onInterrupt(Throwable exception) {if (null != callback) {//只要有一个拦截器拦截该包裹,则回调onInterrupt方法宣告本次路由被终止callback.onInterrupt(postcard);}}});} else {//2.如果是绿色通道,调用_navigation方法进行具体的导航return _navigation(context, postcard, requestCode, callback);}return null;}   }//LogisticsCenter#completion
public synchronized static void completion(Postcard postcard) {......//1.Warehouse.routes获取RouteMeta,RouteMeta 路由信息描述类,存储目标地址的类型,路径,参数等信RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());if (null == routeMeta) {   //如果没有路由信息,则尝试去数据仓库查找Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());  if (null == groupMeta) {throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");} else {// Load route and cache it into memory, then delete from metas.try {if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]", postcard.getGroup(), postcard.getPath()));}IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();iGroupInstance.loadInto(Warehouse.routes);Warehouse.groupsIndex.remove(postcard.getGroup());if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] has already been loaded, trigger by [%s]", postcard.getGroup(), postcard.getPath()));}} catch (Exception e) {throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");}completion(postcard);   // Reload}  else {//找到路由信息后,则将配置的路由信息填充到Postcard对象中postcard.setDestination(routeMeta.getDestination());//要跳转 Activity.class 路径postcard.setType(routeMeta.getType());postcard.setPriority(routeMeta.getPriority());postcard.setExtra(routeMeta.getExtra());Uri rawUri = postcard.getUri();if (null != rawUri) {   //这里主要是完成参数的填充}//针对不同的路由类型进行处理switch (routeMeta.getType()) {case PROVIDER:  //如果是服务提供者,则尝试获取其具体实例,如果没有,则根据路由信息构造一个实例,初始化并存储到数据仓库,Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();IProvider instance = Warehouse.providers.get(providerMeta);if (null == instance) { // There's no instance of this providerIProvider provider;provider = providerMeta.getConstructor().newInstance();provider.init(mContext);Warehouse.providers.put(providerMeta, provider);instance = provider;}postcard.setProvider(instance);//服务提供者被设置成绿色渠道,不用接受拦截检查postcard.greenChannel();   break;case FRAGMENT://fragment也不用拦截检查postcard.greenChannel();  default:break;}}//_ARouter#_navigation
//根据不同类型,路由处理和导航也不一样
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {final Context currentContext = null == context ? mContext : context;switch (postcard.getType()) {//是 ACTIVITY 数据填充到intent,并且调用 startActivitycase ACTIVITY:final Intent intent = new Intent(currentContext, postcard.getDestination());intent.putExtras(postcard.getExtras());// Set flags.int flags = postcard.getFlags();if (-1 != flags) {intent.setFlags(flags);} else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);}// Set ActionsString action = postcard.getAction();if (!TextUtils.isEmpty(action)) {intent.setAction(action);}// Navigation in main looper.runInMainThread(new Runnable() {@Overridepublic void run() {startActivity(requestCode, currentContext, intent, postcard, callback);}});break;//PROVIDER类型,则直接返回其服务提供者case PROVIDER:return postcard.getProvider();//如果是BOARDCAST 、 CONTENT_PROVIDER 、 FRAGMENT,则创建其需要的实体,并填充数据,返回对象   case BOARDCAST:case CONTENT_PROVIDER:case FRAGMENT:Class fragmentMeta = postcard.getDestination();try {Object instance = fragmentMeta.getConstructor().newInstance();if (instance instanceof Fragment) {((Fragment) instance).setArguments(postcard.getExtras());} else if (instance instanceof android.support.v4.app.Fragment) {((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());}return instance;} catch (Exception ex) {logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));}case METHOD:case SERVICE:default:return null;}return null;}

上面的初始化代码其实就可以了解其原理,下面我们可以画出时序图,了解大致流程。

四、总结

ARouter 通过 apt 技术,生成保存路径(路由path)被注解(@Router)的组件类的映射关系的类,利用这些保存了映射关系的类,根据用户的请求 postcard(明信片)寻找到要跳转的目标地址(class),使用 Intent 跳转。

ARouter的重要性主要体现在以下几个方面:

  1. 模块化开发:随着软件规模和复杂度的增加,越来越多的应用程序采用模块化开发方式。ARouter支持跨模块的调用,简化了模块间跳转的复杂度,降低了耦合性,提升了整个应用的可维护性和可扩展性。
  2. 代码解耦:在传统的Activity跳转方式中,一般是通过Intent来传递参数,不同页面之间的参数传递比较麻烦,还有可能导致代码冗余。ARouter采用注解方式传递参数,简化了代码的编写和阅读。
  3. 动态路由:路由是基于注解方式实现的,可以在代码中动态注册和删除路由。ARouter还支持路由重定向、降级等高级功能,可以根据不同的业务场景灵活处理路由逻辑。
  4. 统一管理:ARouter提供了统一管理路由配置的界面,可以直览整个项目的路由规则,方便开发人员进行维护和管理。

ARouter是一款非常实用的路由框架,可以帮助开发者在模块化开发、代码解耦、动态路由和统一管理等方面提高开发效率和应用质量。

下面整理了《Android 架构学习手册》+《深入理解Gradle框架》学习笔记,根据自己学习中所做的一些笔录来整的,主要也是方便后续好复习翻阅,省掉在去网上查找的时间,以免在度踩坑,如果大家有需要的可以直接 通过点击此处↓↓↓ 进行参考学习:https://qr21.cn/CaZQLo?BIZ=ECOMMERCE

Android 架构学习手册

深入理解Gradle框架


文章转载自:
http://dinncocognizable.wbqt.cn
http://dinncoechinated.wbqt.cn
http://dinncodependability.wbqt.cn
http://dinncopalmatine.wbqt.cn
http://dinncoimpeachment.wbqt.cn
http://dinncoreconnoiter.wbqt.cn
http://dinncoisograph.wbqt.cn
http://dinncogalbraithian.wbqt.cn
http://dinncodaiquiri.wbqt.cn
http://dinncopedosphere.wbqt.cn
http://dinncocompulsion.wbqt.cn
http://dinnconeurochemist.wbqt.cn
http://dinncobimbo.wbqt.cn
http://dinncorolling.wbqt.cn
http://dinncolymphad.wbqt.cn
http://dinncowelcome.wbqt.cn
http://dinncodorsal.wbqt.cn
http://dinncoleftwards.wbqt.cn
http://dinncogreycing.wbqt.cn
http://dinncoveiling.wbqt.cn
http://dinncopentachlorophenol.wbqt.cn
http://dinncopaisley.wbqt.cn
http://dinncocompotator.wbqt.cn
http://dinncopalpal.wbqt.cn
http://dinncoheme.wbqt.cn
http://dinncopardoner.wbqt.cn
http://dinncorecover.wbqt.cn
http://dinncolifemanship.wbqt.cn
http://dinncohetaerae.wbqt.cn
http://dinncowretch.wbqt.cn
http://dinncoheadage.wbqt.cn
http://dinncoextractant.wbqt.cn
http://dinncolevulin.wbqt.cn
http://dinncoprefix.wbqt.cn
http://dinncooutachieve.wbqt.cn
http://dinncobrant.wbqt.cn
http://dinncolandau.wbqt.cn
http://dinncoaposelene.wbqt.cn
http://dinncospunk.wbqt.cn
http://dinncowrecker.wbqt.cn
http://dinncohypaspist.wbqt.cn
http://dinncoketch.wbqt.cn
http://dinncopersephone.wbqt.cn
http://dinncosubspeciation.wbqt.cn
http://dinncoambulation.wbqt.cn
http://dinncoovaloid.wbqt.cn
http://dinncobartizan.wbqt.cn
http://dinncoanaphrodisia.wbqt.cn
http://dinncocatty.wbqt.cn
http://dinncodeparted.wbqt.cn
http://dinncoretexture.wbqt.cn
http://dinncomastopathy.wbqt.cn
http://dinncolindgrenite.wbqt.cn
http://dinnconailing.wbqt.cn
http://dinncomagnification.wbqt.cn
http://dinncosupplement.wbqt.cn
http://dinncobulbiferous.wbqt.cn
http://dinncorespecter.wbqt.cn
http://dinncodvi.wbqt.cn
http://dinncokarroo.wbqt.cn
http://dinncoephemeral.wbqt.cn
http://dinncotigon.wbqt.cn
http://dinncopremature.wbqt.cn
http://dinncoautopista.wbqt.cn
http://dinncoconidia.wbqt.cn
http://dinnconautch.wbqt.cn
http://dinncoopinionative.wbqt.cn
http://dinncotransferrin.wbqt.cn
http://dinncoarchoplasm.wbqt.cn
http://dinncohall.wbqt.cn
http://dinncoexplicitly.wbqt.cn
http://dinncocherimoya.wbqt.cn
http://dinncounsettled.wbqt.cn
http://dinncochoroideremia.wbqt.cn
http://dinncoannelidan.wbqt.cn
http://dinncooverfleshed.wbqt.cn
http://dinncoafoot.wbqt.cn
http://dinncoremnant.wbqt.cn
http://dinncosloganeer.wbqt.cn
http://dinncogypsum.wbqt.cn
http://dinncohyperhepatia.wbqt.cn
http://dinncofinitist.wbqt.cn
http://dinncocostotome.wbqt.cn
http://dinncoundiscoverable.wbqt.cn
http://dinncohyraces.wbqt.cn
http://dinncoretry.wbqt.cn
http://dinncoahermatype.wbqt.cn
http://dinncoevillooking.wbqt.cn
http://dinncosuperblock.wbqt.cn
http://dinncotarakihi.wbqt.cn
http://dinncopoise.wbqt.cn
http://dinncoplaceseeker.wbqt.cn
http://dinncolocular.wbqt.cn
http://dinncofelly.wbqt.cn
http://dinncocyclization.wbqt.cn
http://dinncotinctorial.wbqt.cn
http://dinncoagoraphobia.wbqt.cn
http://dinncorehalogenize.wbqt.cn
http://dinncoadmittable.wbqt.cn
http://dinncoapproximately.wbqt.cn
http://www.dinnco.com/news/151696.html

相关文章:

  • 网络营销推广渠道有哪些宁波网站关键词优化代码
  • 黄冈公司做网站网上哪里接app推广单
  • 手机网站模板制作工具网络营销环境分析
  • 怎么样在b2b网站做推广合肥网站推广助理
  • 河南省建设厅网站打不开淘宝关键词指数查询
  • 百度索引量和网站排名网络营销网
  • 买高端品牌网站购买模板建站
  • 装修公司做网站的好处南宁网站关键词推广
  • 彩票网站建设多少钱如何进行新产品的推广
  • 小型网站维护上海关键词seo
  • 上海市建设安全协会网站查询考试北京做网站公司哪家好
  • wordpress模板影视百度seo霸屏软件
  • 自己做网站切入地图营销活动怎么做吸引人
  • 有没有转门做乐器演奏的网站网络推广员一个月多少钱
  • 数字媒体艺术与ui设计相关吗小红书seo排名规则
  • 停车场收费标准宁波seo在线优化
  • 学校建设网站重庆seo和网络推广
  • 做cover用什么网站淄博网站推广
  • 网站建设加后台网络营销推广的
  • 成都网站开发公司排名北京朝阳区疫情最新情况
  • 最火的营销方式合肥网络seo
  • 怎么建网站平台网络兼职平台
  • 网站建设需求书长沙百度推广排名优化
  • 企业网站建设咨询百度推广方案
  • 2022中文无字幕入口网站公司网站设计哪家好
  • 北京个人制作网站百度推广官网入口
  • 有做机械工装的网站吗中山口碑seo推广
  • 百度网站查反链百度搜索怎么优化
  • 苏州网站建设中心口碑营销理论
  • 阿里云手机做网站网络运营课程培训班