android 短信 aapp,谈谈App的统一跳转和ARouter

App中每次页面跳转,都需要调用统一导航, 它用的非常频繁, 有必要对它进行一下梳理. 让他能用起来简单方便, 同时能支持各种常用的跳转业务场景.

一. Android跳转遇到的问题

1.intent-filter跳转不好管理

Intent intent = new Intent();

intent.setAction(Intent.ACTION_SENDTO);

intent.setData(Uri.parse("smsto:10086"));

context.startActivity(intent);

如果项目分多个Module, Activity需要在各自Module的AndroidManifest.xml中声明,容易重复,不好统一管理.

2.Activity class跳转耦合性高

//通过设置目标class跳转

Intent intent = new Intent();

intent.setClass(context,TargetActivity.class);

context.startActivity(intent);

A如果要跳转到TargetActivity, A要引用到TargetActivity. 造成:

如果项目多个Module开发,底层module不能跳转到高层Activity

如果TargetActivity类名变化, 对应调用方都需要改动

3. 混合开发时,H5/Weex跳转新界面不方便

内置H5要跳转 Native页面, 通过JsBidge把目标信息传过来.

两种方式:

方式1: 直接提供目标Activity的 Action 跳过去.

方式2: Native维护一个的Map, H5传过来Activiy的"描述", Native在Map中查到后,进行跳转.

方式1的问题:

一般H5会同时在"Android/ios"容器中, 所以最好的实践是:H5做跳转时不需要区分平台和版本. 如果利用Action跳转,

1)Action命名要符合两个平台的规范

2)如果Native不支持目标Action,还需要做跳转失败后处理.

方式2的问题:

1)维护的列表麻烦事,需要单独角色管理.

2)同样存的"Activity信息"也有问题1,2中提到的问题

都有的问题:

处理跳转的Bridge类,可能拿不到context,这需要拿Application的Context,大家都判断略嫌麻烦.

4.跳转到"未知页面"的统一处理

比如2.0版本新加了"消息"功能,App1.0版本没有.

此时1.0版本的App中,"H5/push" 尝试打开"消息"页面, 肯定是不支持的. 这时候有几种策略:

H5/Push能判断Native支持页面的能力,如果不支持,就不调用

Native收到调用未知页面, 不做任何动作.

Native收到调用未知页面, 提示这是新版功能,建议更新版本.

5. 业务降级/重定向

比如A/B测试:

Native可以根据配置, 跳转不同的实现页面

业务降级:

某个业务本来Native实现, 降级为H5实现, 这时候跳转时切换到H5页面.

6.统一加参

跳转到目标页面前,能统一加参数.

实现比如打点, 添加通用参数操作.

7.外部调用的统一入口

考虑这种业务场景: App有 A,B,C三个页面, 提供给外部调用.

这时候一般两种实现方式:

方式1: A,B,C的Activity 在AndroidManifest.xml中export=true,并且设置 intent-filter

方式2: App设置一个统一的Router-Activity, 外部跳转到A,B,C 都统一先统一到Router-Activity, 他在拉起A,B,C

方式1分析:

除非真的提供通用的功能(拍照/图片处理/..)给外部调用, 否则export一个Activity是不必要也不安全的. 为了安全,App不会export大量的Activity. 这意味着通过这种机制, 外部能调用内部的功能较少.

方式2分析:

优点:

只暴露了一个Router-Activity. 安全和好管理.

Router-Activity里面可以做一些调用者的安全校验, 如果校验通过可以运行跳转App的全部页面. 这样给能外部调用app更多页面的机会, 也兼顾了安全.

缺点:

外部跳转需要一个Activity中转一下,直观上感觉效率低一些. 但是实际感觉基本没有影响.

二. 明确需求

根据问题和业务场景, 我们的"统一跳转"的需求也基本明确:

"声明/使用" 简单.

适用多module开发,避免直接依赖.

统一协议, 适用"H5/Weex/Native" 跳转 "Native", 对"Android/ios"两个平台协议应该是一样的.

有统一的外部调用入口

能对"不支持"的跳转统一处理

支持跳转前预处理

支持重定向

三.解决方案ARouter

ARouter

ARouter-github 很好的解决了上述问题.

下面是他的对应的方案.

1.使用简单:

每个Activity在类中自声明,"代码-路径"对应一目了然

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

public class YourActivity extend Activity {

...

}

跳转新页面简单,不需要知道目标ActivityContext,intent-filter,目标的Activity

ARouter.getInstance().build(path).with(bundle).navigation();

2.页面利于统一管理

所有页面可以统一定义. 一目了然

String PAGE_MAIN = "/navigateTo/main";

String PAGE_H5 = "/navigateTo/h5";

String PAGE_WEEX = "/navigateTo/weex";

...

3.便于设置统一Activity承载外部跳转

public class SchameFilterActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//安全/版本校验

....

Uri uri = getIntent().getData();

ARouter.getInstance().build(uri).navigation();

finish();

}

}

4.处理"未知页面"的跳转结果

ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {

@Override

public void onFound(Postcard postcard) {

...

}

@Override

public void onLost(Postcard postcard) {

//可以处理,提示升级版本之类

}

});

5. 自定义全局降级策略

// 实现DegradeService接口,并加上一个Path内容任意的注解即可

@Route(path = "/xxx/xxx")

public class DegradeServiceImpl implements DegradeService {

@Override

public void onLost(Context context, Postcard postcard) {

// do something.

}

@Override

public void init(Context context) {

}

}

6. 重写跳转URL实现重定向

// 实现PathReplaceService接口,并加上一个Path内容任意的注解即可

@Route(path = "/xxx/xxx") // 必须标明注解

public class PathReplaceServiceImpl implements PathReplaceService {

/**

* For normal path.

*

* @param path raw path

*/

String forString(String path) {

return path; // 按照一定的规则处理之后返回处理后的结果

}

/**

* For uri type.

*

* @param uri raw uri

*/

Uri forUri(Uri uri) {

return url; // 按照一定的规则处理之后返回处理后的结果

}

}

技术分析

1.建立 Url-Activity 的对应关系

ARouter最后是通过下面方式跳转的.

//_ARouter.java

Intent intent = new Intent(currentContext,postcard.getDestination());

intent.putExtras(postcard.getExtras());

所以要AROUTER需要维护一个 Path和Activity class的对应关系.

他利用

javapoet在编译时候生成类信息

初始化时,收集主创Path/Activity信息. 所有信息存在WareHouse中.

c0eecbbf1481

screenshot.png

2. 跳转流程

c0eecbbf1481

screenshot.png

其他技术

1. 属性设置在gradle.properties中

BUILDTOOLS_VERSION=25.0.0

使用:

compile "com.android.support:support-v4:${SUPPORT_LIB_VERSION}"

buildToolsVersion BUILDTOOLS_VERSION

2.TreeMap

HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)

3.Instrumentation的使用

你可以将Instrumentation理解为一种没有图形界面

的,具有启动能力的,用于监控其他类(用Target

Package声明)的工具类。任何想成为Instrumentation的类必须继承android.app.Instrumentation。

下面是这个类的解释:

“Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml's tag.“

4.volatile

volatile重要工作是避免线程脏读:当线程对volatile变量进行读操作时,会先将2. 自己工作内存中的变量置为无效,之后再通过主内存拷贝新值到工作内存中使用。

volatile解决的是变量在多个线程之间的可见性,但不能完全保证数据的原子性。

现在JVM经过优化,已不会出现liveness failure 。所以没事别用volatile。

5. CountDownLatch

CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。

6.获取CPU个数

CPU_COUNT = Runtime.getRuntime().availableProcessors()

7.捕捉线程异常

// 捕获多线程处理中的异常

thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

@Override

public void uncaughtException(Thread thread, Throwable ex) {

ARouter.logger.info(Consts.TAG, "Running task appeared exception! Thread [" + thread.getName() + "], because [" + ex.getMessage() + "]");

}

});

build classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'

使用 annotationProcessor

dependencies {

annotationProcessor project(':arouter-compiler')

}

9.Activity启动

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);

}

10. 访问者模式

//设置WareHouse

public interface IRouteGroup {

/**

* Fill the atlas with routes in group.

*/

void loadInto(Map atlas);

}

iGroupInstance.loadInto(Warehouse.routes);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 自定义spnner弹出框,PopupWindow,ListView实现自定义Spinner

最终的效果图,点击86弹出popup这里写图片描述PupupWindow的布局文件为一个ListView 作为pupup的主体内容android:orientation"vertical"android:layout_width"match_parent"android:layout_height"match_parent">android:id"id/register…

hdu 6026 Deleting Edges(最短路计数)

题目链接:hdu 6026 Deleting Edges 题意: 给你n个点,和一个邻接矩阵,非0表示有边,0表示没边。 现在让你删一些边,构成一棵树,使得每个点到0这个点的距离为没删边之前的最短路。 问有多少棵这样的…

Xamarin XAML语言教程构建进度条ProgressBar

Xamarin XAML语言教程构建进度条ProgressBar Xamarin XAML语言教程构建进度条ProgressBar,ProgressBar被称为进度条,它类似于没有滑块的滑块控件。进度条总是水平放置的。本节将讲解如何使用进度条。注意:进度条在各个平台下基本相同&#xf…

mac删除android sd卡,如何从mac完全删除android及其所有文件?

前一段时间我试图让科尔多瓦工作,但android模拟器永远不会启动。它只是挂着一个黑色的屏幕。如何从mac完全删除android及其所有文件?我原来是用brew install android-sdk安装的。然后我读了一个糟糕的地方。所以我已经删除它并安装了Android Studio。无论…

201521123023《Java程序设计》第13周学习总结

1. 本周学习总结 (1)网络中为了进行数据交换(通信)而建立的规则、标准或约定(语义语法规则)称之为协议(常用http/ftp) (2)大致熟悉了TCP协议,但是UDP怎么辣么蓝&#xff…

QML与C++交互:登陆界面设计

QML与C交互:登陆界面设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:Qt5.2.1 说明: QML设计前台界面,C后台负责逻辑 效果图: 源码: 前台qml文件 login.qml /******************************************************…

html怎么在字体中加波浪线,CSS3实现文字波浪线效果

前言css的设计之巧妙,实现之精妙,细细寻味,其妙非凡,妙不可言。这波浪线,取巧的运用了linear-gradient属性,合角度、颜色、位置于一体,配合background-size,background-repeat&#…

NET Core 指令启动

ASP.NET Core 是新一代的 ASP.NET,早期称为 ASP.NET vNext,并且在推出初期命名为ASP.NET 5,但随着 .NET Core 的成熟,以及 ASP.NET 5的命名会使得外界将它视为 ASP.NET 的升级版,但它其实是新一代从头开始打造的 ASP.N…

html文本显示状态代码中,HTML文本显示状态代码中,表示?

文本如何大小判别偏心受压剪力墙的。能源能量然资提供的自是指源,显示如(,显示能、能、能、能、、热等的械能是机生物原子光能化学总称,不可能源然界的一可再生能于自源可源和再生分为存在次能。状态中表并发儿麻体温生的婴幼易发间低醉期症(…

[LeetCode]Distinct Subsequences,解题报告

题目 Given a string S and a string T, count the number of distinct subsequences of T in S.A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative po…

2021年河南高考成绩排名查询一分一段表,2018河南高考一分一段统计表,查排名必备!...

原标题:2018河南高考一分一段统计表,查排名必备!:点击这里信息省招办公布了2018年普通高招分数段统计表,对每个分数段有多少考生进行了详细统计。你考了多少分?处在哪个位置?快来看看&#xff0…

实用的css样式

当字数超过一行时,可以用...代替 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 这三个样式同时使用才有效,也可以去掉white-space样式,分两行 转载于:https://www.cnblogs.com/maggie-php/p/6906462.html

(2021|CoRR,AugCLIP,优化)FuseDream:通过改进的 CLIP+GAN 空间优化实现免训练文本到图像生成

FuseDream: Training-Free Text-to-Image Generation with Improved CLIPGAN Space Optimization 公众:EDPJ(添加 VX:CV_EDPJ 或直接进 Q 交流群:922230617 获取资料) 目录 0. 摘要 1. 简介 2. CLIPGAN 文本到图…

中文邮件营销html模版,怎么制作邮件营销模板?— —邮件格式

怎么制作邮件营销模板?— —邮件格式U-Mail邮件营销平台发表时间 2017-09-21人气 757次做EDM邮件营销,需要有好的邮件群发工具,还要有好的内容,那么如何制作好邮件营销的模板呢?现在U-Mail邮件群发平台根据已有的一些经…

angularJS中,怎么阻止事件冒泡

今天有个童鞋问我,ng怎么阻止事件冒泡,我就简单的贴一下代码吧,也不是什么好高大上的问题 转载于:https://www.cnblogs.com/leoshuaige/p/6910646.html

用计算机画好看的图形,如何画一手漂亮的电脑效果图?技巧案例赏析!

原标题:如何画一手漂亮的电脑效果图?技巧&案例赏析!电脑效果图是什么?很显然,用电脑去绘制设计师的想法。当然!所有的设计意图,最终都是为了更准确的成衣。那么,能精准的表达出想…

适合文科女孩子学的计算机类专业,文科女生最吃香的专业2021 哪些专业有前景...

文科女生最吃香的专业2021 哪些专业有前景2021-03-27 14:36:27文/丁雪竹文科女生可以报考的专业并不是很多,小编整理了文科女生吃香的专业,来看一下!文科女生最吃香的专业网络与新媒体这个专业是近几年流行起来的新兴专业,需求量还…

Ubuntu16.04下Mongodb官网安装部署步骤(图文详解)(博主推荐)

不多说,直接上干货! 在这篇博客里,我采用了非官网的安装步骤,来进行安装。走了弯路,同时,也是不建议。因为在大数据领域和实际生产里,还是要走正规的为好。 Ubuntu16.04下Mongodb(离…

uva 11971 Polygon

https://vjudge.net/problem/UVA-11971 有一根长度为n的木条&#xff0c;随机选k个位置把它们切成k1段小木条。求这些小木条能组成一个多边形的概率。 将木条看做一个圆&#xff0c;线上切k刀等价于圆上切k1刀 如果能组成多边形&#xff0c;每一段木条的长度都要<圆周长/2 反…

Charles - 接口抓包分析工具

Charles是一个HTTP代理服务器&#xff0c;反转代理服务器&#xff0c;HTTP监视器。它允许一个开发者查看所有连接互联网的HTTP通信&#xff0c;包括request、 response现HTTP headers &#xff08;包含cookies与caching信息&#xff09;。 下载&#xff1a; http://www.charle…