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这个点的距离为没删边之前的最短路。 问有多少棵这样的…

android 服务端 导入工程,如何导入与配置从网上下载的android源代码及服务器端源代码...

将Android项目导入import进Eclipse。 注意SDK版本是否匹配 。 服务器部署到Tomcat下。 你得在数据库中将这个点菜系统的数据库和表建好,或者导入。在服务器的代码中修改好你的数据库名和密码。首先看你的服务器配置的是什么环境 一般就2种 linux系统 window系统&…

mysql: 模糊查询 feild like keyword or feild like keyword , concat(feild1,feild2,feild3) like keyword...

mysql: 模糊查询 feild like %keyword% or feild like% keyword% , 或者 concat(feild1,feild2,feild3) like %keyword% 转载于:https://www.cnblogs.com/achengmu/p/6877852.html

android按钮控件常见问题,Android的基本控件和Activity的应用总结

Android的基本控件常用界面控件TextView 显示文本信息button 普通按钮EditText 可编辑的文本框组件(输入框)ImageView 用于显示图片ImageBUtton 图片按钮CheckBox 复选框RadioGroup 单选按钮组Spinner 下拉列表组件ProgressBar进度条SeekBar拖动条RatingBar评分组件ListView列表…

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

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

android tv字体,best登陆「永久地址0365.tv」android默认字体android使用代码使用新的字体的常用代码...

页面类类名称:MainActivitypackage com.example.android_fonts_test;import android.support.v7.app.ActionBarActivity;import android.content.Context;import android.graphics.Typeface;import android.os.Bundle;import android.view.Menu;import android.view…

android 交叉编译so,Android交叉编译htop和使用方法

htop来源于top,top是Unix/linux下功能强大的性能检测工具之一,用于实时检测并统计进程的属性和状态,基于ncurses库,可上显示文字界面。但是top已经非常陈旧,不支持鼠标点击操作,不支持查看进程的各个子线程…

Java笔记(08):面向对象--抽象类

1、抽象类概述: 1 /*2 抽象类的概述:3 动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。4 我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该…

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…

Android中怎获取json,Android应用中如何解析获取的json数据

Android应用中如何解析获取的json数据发布时间:2020-11-24 17:10:08来源:亿速云阅读:107作者:Leah这篇文章将为大家详细讲解有关Android应用中如何解析获取的json数据,文章内容质量较高,因此小编分享给大家…

Hibernate4之session核心方法

在学习session的核心方法之前,我们先了解下hibernate中几种对象的状态: 暂时状态:这样的状态就好像咱们公司请的暂时员工一样,他在公司里没有相关的资料和id。 特点:在使用代理主键的情况下, OID 通常为 null 不…

Android 同步锁死锁,Android多线程研究(3)——线程同步和互斥及死锁

为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码:package com.maso.test;public class ThreadTest2 implements Runnable{private TestObj testObj new TestObj();public static void main(String[] args)…

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文本显示状态代码中,表示?

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

1807. [NOIP2014]寻找道路P2296 寻找道路

题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。 2 .在满足…

html页面 wordpress,WordPress纯代码实现前端页面HTML完美压缩

前言:压缩HTML页面的好处就是略微提升页面加载速度,并给那些爱扒皮的缺德玩意制造些许麻烦。好了将如下代码添加在functions.php中即可://压缩WordPress前端html代码function wp_compress_html(){function wp_compress_html_main ($buffer){$…