模块化开发项目中页面跳转问题很重要,本文主要介绍了Router解决跨模块下的页面跳转示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。
一、前言
开始模块化开发项目之后,一个很重要的问题就是页面见的跳转问题。
关于模块化发开,可详见我的另一片文章 Android模块化开发探索 。
正是由于将项目模块化拆分,各模块之间没有任何依赖关系,也互相不可见,那么从A模块的a界面跳转到B模块的b界面该怎么办呢?
二、跨模块跳转的方法
这里我们会先介绍这几种常见的跳转方法:
显示跳转
隐示跳转
Scheme协议跳转
Router路由表方案
2.1 显示跳转
显示跳转即我们最最常用的跳转方法:使用Intent,传入当前Activity上下文,和目标Activity的class对象即可,如下:
Intent intent = new Intent(); intent.setClass(mContext, GuideActivity.class); startActivity(intent);
显然,这种方法只能是目标Activity可见(Activity在同一个Module下)的时候才可以这样调用。不适合跨模块间的跳转。
2.2 隐示跳转
我们这里说的隐示跳转,intent不设置class,而是设置Action或者Category。
例如:
在清单文件中
<!--网页展示界面--> <activity android:name="com.whaty.base.BaseWebViewActivity" android:hardwareAccelerated="true"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="com.whaty.base.BaseWebViewActivity" /> </intent-filter> </activity>
跳转时:
//创建一个隐式的 Intent 对象:Action 动作 Intent intent = new Intent(); //设置 Intent 的动作为清单中指定的action intent.setAction("com.whaty.base.BaseWebViewActivity"); startActivity(intent);
2.3 scheme跳转
如果我们为 B 页面定义一个 URI - wsc://home/bbb,然后把共享的 messageModel 拍平序列化成 Json 串,那么 A 只需要拼装一个符合 B 页面 scheme 的跳转协议就可以了。 wsc://home/bbb?message={ “name”:”John”, “age”:31, “city”:”New York” }
在清单文件中,配置data属性,设置其host、path、scheme等
<activity android:name=".ui.BbbActivity" <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW" /> <data android:host="bbb" android:path="/home" android:scheme="wsc" /> </intent-filter> </activity>
跳转时:
final Uri uri = new Uri.Builder().authority("wsc").path("home/bbb").appendQueryParameter("message", new Gson().toJson(messageModel)).build(); final Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(uri); startActivity(intent);
以上的方法,都不是我们想要的,接下来开始介绍我们的Router方案。
三、为什么要用Router
Google提供了显式和隐式两种原生路由方案。但在模块化开发中,显式Intent存在类直接依赖的问题,造成模块间严重耦合。隐式Intent则需要在Manifest中配置大量路径,导致难以拓展(如进行跳转拦截)。为了解决以上问题,我们需要采用一套更为灵活的Router方案。
四、实现思路
思路是这样的:
使用注解,为每个目标Activity标注别名。在应用启动时,对所有类进行扫名,将注解过的Activity存于路由表中。
跳转时,在路由表中通过别名获取目标Activity的class对象,使用Intent实现跳转。
五、代码实现
5.1 自定义注解
/** * Description: 路由跳转界面 注解 * Created by jia on 2018/1/10. * 人之所以能,是相信能 */ @Target(ElementType.TYPE) //注解作用于类型(类,接口,注解,枚举) @Retention(RetentionPolicy.RUNTIME) //运行时保留,运行中可以处理 @Documented // 生成javadoc文件 public @interface Action { String DEFAULT = "js"; String value() default DEFAULT; }
关于自定义注解的详细介绍,请阅读我的文章java进阶之自定义注解。这里不再多说。
5.2 注解Activity
@Action("MainActivity") public class MainActivity extends BaseActivity implements TabLayout.OnTabSelectedListener { ... }
在创建Activity时,用刚刚自定义的注解进行注解,为其注释别名。
5.3 启动时扫描
private void getAllActivities(Context ctx){ try { //通过资源路径获得DexFile DexFile e = new DexFile(ctx.getPackageResourcePath()); Enumeration entries = e.entries(); //遍历所有元素 while(entries.hasMoreElements()) { String entryName = (String)entries.nextElement(); //匹配Activity包名与类名 if(entryName.contains("activity") && entryName.contains("Activity")) { //通过反射获得Activity类 Class entryClass = Class.forName(entryName); if(entryClass.isAnnotationPresent(Action.class)) { Action action = (Action)entryClass.getAnnotation(Action.class); this.map.put(action.value(), entryClass); } } } } catch (Exception e) { e.printStackTrace(); } }
在应用启动时,Application中对包下的所有类进行扫描,先找到名字中到activity的(定义到activity包下),并将带有注解标注的Activity,存入map中。
5.4 跳转
/** * 页面跳转 * @param activity * @param alias */ public void jumpActivity(Activity activity, String alias) throws ClassNotFoundException{ if(map.containsKey(alias)) { Intent intent = new Intent(activity, map.get(alias)); activity.startActivity(intent); } else { throw new ClassNotFoundException(); } }
跳转的时候传入目标Activity的别名即可(这里的别名就是注解的别名)。
总结
通过这种方式,解决了跳转Activity所产生的的模块依赖问题,相较于原生方案,拓展性更强。但这种方案只是阶段性的,还存在一些问题。首先,加载过程中,频繁使用到反射,会产生性能问题。其次,对于每个Activity的别名,需要进行统一维护,增加了协作成本。还有待优化。
当然,市面上有很多流行的Router方案(如阿里的ARouter),这里只是介绍了一个思路,有好的建议欢迎交流,一起进步。
相关推荐:
以上是Router解决跨模块下的页面跳转的详细内容。更多信息请关注PHP中文网其他相关文章!

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

Atom编辑器mac版下载
最流行的的开源编辑器

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

禅工作室 13.0.1
功能强大的PHP集成开发环境

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中