为什么会用到路由跳转,一般我们在项目中基本使用这种方式
Intent intent = new Intent(MainActivity.this, LoanRequestActivity.class);
startActivity(intent);
也可以使用隐式的方式来跳转,不过一般用的少,多数情况是调用第三方Sdk,系统的相机 相册这种三方的,显示的跳转基本就可以实现,但是对于跳转的来源很多的情况就不适合了
,例如推送Web页面,以及其他应用,并且很多地方的跳转需要设置成服务器配置,于是就用到了
路由跳转,以url的字段标志来识别一个activity来统一进行跳转.
调用方式:
应用内模块间跳转:
RouteDispatch.dispatch(MainActivity.this,"/loan/apply");
其他跳转来源:这里采用一个中间Activity来跳转
public class RouteDispatchActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RouteDispatch.dispatch(this);
this.finish();
}
实现步骤:
1.构建路由对象
public class Route {
//自定义的Scheme 和 Host
public static final String JS_SCHEMA = "js";
public static final String PUSH_SCHEMA = "push";
public static final String APP_SCHEMA = "renwohua";
public static final String HTTP_SCHEMA = "http";
public static final String HTTPS_SCHEMA = "https";
public static final String HOST = "com.renwohua.conch";
private Class> activityClass;
private Uri mUri;
//将 url 和 Activity 组成Route对象
public Route(String uri, Class> activityClass) {
this.mUri = Uri.parse(uri);
this.activityClass = activityClass;
}
public boolean isJS() {
if(this.mUri == null) {
throw new NullPointerException("uri == null");
} else {
return "js".equals(this.mUri.getScheme()) && "com.renwohua.conch".equals(this.mUri.getHost());
}
}
public static boolean isJS(String url) {
if(url == null) {
throw new NullPointerException("url == null");
} else {
Uri uri = Uri.parse(url);
return "js".equals(uri.getScheme()) && "com.renwohua.conch".equals(uri.getHost());
}
}
public boolean isPush() {
if(this.mUri == null) {
throw new NullPointerException("uri == null");
} else {
return "push".equals(this.mUri.getScheme()) && "com.renwohua.conch".equals(this.mUri.getHost());
}
}
public boolean isAPP() {
if(this.mUri == null) {
throw new NullPointerException("uri == null");
} else {
return "renwohua".equals(this.mUri.getScheme()) && "com.renwohua.conch".equals(this.mUri.getHost());
}
}
public static boolean isAPP(String url) {
if(url == null) {
throw new NullPointerException("url == null");
} else {
Uri uri = Uri.parse(url);
return "renwohua".equals(uri.getScheme()) && "com.renwohua.conch".equals(uri.getHost());
}
}
public boolean isHTTP() {
if(this.mUri == null) {
throw new NullPointerException("uri == null");
} else {
return "http".equals(this.mUri.getScheme()) || "https".equals(this.mUri.getScheme());
}
}
public static boolean isHTTP(String url) {
if(url == null) {
throw new NullPointerException("url == null");
} else {
Uri uri = Uri.parse(url);
return "http".equals(uri.getScheme()) || "https".equals(uri.getScheme());
}
}
public Class> getActivityClass() {
return this.activityClass;
}
}
2.构建路由对象集合
public final class Routes {
private final Map> map = new HashMap();
private static String schema = "renwohua";//默认的schema
private static String host = "com.renwohua.conch";//默认的host
public Routes() {
}
//添加一个路由集合
public Routes add(Routes routes) {
if(routes != null) {
this.map.putAll(routes.map);
}
return this;
}
//添加单个路由
public Routes add(String activityKey, Class extends Activity> activityClass) {
if(activityKey == null) {
throw new IllegalArgumentException("The activityKey can not be null");
} else {
activityKey = activityKey.trim();
if("".equals(activityKey)) {
throw new IllegalArgumentException("The activityKey can not be blank");
} else if("/".equals(activityKey)) {
throw new IllegalArgumentException("The activityKey can not be /");
} else if(activityClass == null) {
throw new IllegalArgumentException("The activityClass can not be null");
} else {
if(!activityKey.startsWith("/")) {
activityKey = "/" + activityKey;
}
if(this.map.containsKey(activityKey)) {
throw new IllegalArgumentException("The activityKey already exists: " + activityKey);
} else {
this.map.put(activityKey, activityClass);
return this;
}
}
}
}
public Set>> getEntrySet() {
return this.map.entrySet();
}
//获取单个路由对象
public Route getRoute(String path) {
Class activityClass = (Class)this.map.get(path);
return activityClass == null?null:new Route(this.getView(path), activityClass);
}
//组装url = schema://host/path
public String getView(String path) {
return schema + "://" + host + path;
}
//外部设置schema
static void setSchema(String schema) {
if(schema == null) {
throw new IllegalArgumentException("The schema can not be null");
} else {
schema = schema.trim();
if("".equals(schema)) {
throw new IllegalArgumentException("The schema can not be blank");
} else {
schema = schema;
}
}
}
//外部设置host
static void setHost(String host) {
if(host == null) {
throw new IllegalArgumentException("The host can not be null");
} else {
host = host.trim();
if("".equals(host)) {
throw new IllegalArgumentException("The host can not be blank");
} else {
host = host;
}
}
}
}
3.Application中配置定义的路由
@Override
public void configRoute(Routes me) {
me.add("/browser", BrowserActivity.class);
me.add("/credit/apply", QuotaApplyActivity.class);
me.add("/credit/work", StyleActivity.class);
。。。
4.路由分发器
public class RouteDispatch {
private static final String TAG = RouteDispatch.class.getSimpleName();
private RouteDispatch() {
throw new AssertionError("No instances.");
}
//根据某个Activity获取Application中定义的路由配置
private static Routes getRoutes(Activity activity) {
if(activity == null) {
throw new NullPointerException("activity == null");
} else {
BaseApplication application = (BaseApplication)activity.getApplication();
return BaseApplication.getRoutes();
}
}
static void dispatch(Activity activity) {
if(activity == null) {
throw new NullPointerException("activity == null");
} else {
dispatch(activity, activity.getIntent());
}
}
//根据不同的来源url组装不同的path路径,去启动与之对应的Activity
public static void dispatch(Activity activity, String url) {
if(activity == null) {
throw new NullPointerException("activity == null");
} else if(url == null) {
throw new IllegalArgumentException("The url can not be null");
} else {
url = url.trim();
if("".equals(url)) {
throw new IllegalArgumentException("The url can not be blank");
} else {
Log4a.d(url);
Uri uri = Uri.parse(url);
String path = "";
String params = "";
if(StringKit.isEmpty(uri.getScheme())) {
path = uri.getPath();
} else if(!uri.getScheme().equals("http") && !uri.getScheme().equals("https")) {//来自app
if(!uri.getScheme().equals("renwohua")) {
Log4a.e(TAG, new Object[]{"No registered route to handle uri:" + uri.toString()});
return;
}
path = uri.getPath();//
if(uri.getQueryParameterNames().size() > 0) {
params = "?" + uri.getQuery();
}
} else {//来自网络
path = "/browser";
params = "?url=" + Uri.encode(url);
}
dispatch(activity, path, params);
}
}
}
//根据path Params 组建url 添加到Intent中
public static void dispatch(Activity activity, String path, String params) {
if(activity == null) {
throw new NullPointerException("activity == null");
} else if(path == null) {
throw new IllegalArgumentException("The path can not be null");
} else {
path = path.trim();
if("".equals(path)) {
throw new IllegalArgumentException("The path can not be blank");
} else {
Log4a.d(path);
Routes routes = getRoutes(activity);
if(StringKit.isEmpty(params)) {
params = "";
} else {
params = params.startsWith("?")?params:"?" + params;
}
String view = routes.getView(path) + params;
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(view));
dispatch(activity, intent);
}
}
}
//跳转 并将Params放置到Intent中
public static void dispatch(Activity activity, Intent sourceIntent) {
if(activity == null) {
throw new NullPointerException("activity == null");
} else if(sourceIntent == null) {
throw new NullPointerException("sourceIntent == null");
} else {
Uri uri = sourceIntent.getData();
if(uri == null) {
Log4a.e(TAG, new Object[]{"No Uri in given activity\'s intent."});
} else {
Routes routes = getRoutes(activity);
Route entry = routes.getRoute(uri.getPath());
if(entry == null) {
Log4a.e(TAG, new Object[]{"No registered route to handle uri:" + uri.toString()});
} else {
Bundle parameters = null;
if(sourceIntent.getExtras() != null) {
parameters = new Bundle(sourceIntent.getExtras());
} else {
parameters = new Bundle();
}
Iterator c = uri.getQueryParameterNames().iterator();
while(c.hasNext()) {
String newIntent = (String)c.next();
parameters.putString(newIntent, uri.getQueryParameter(newIntent));
}
Class c1 = entry.getActivityClass();
Intent newIntent1 = new Intent(activity, c1);
if(newIntent1.getAction() == null) {
newIntent1.setAction(sourceIntent.getAction());
}
if(newIntent1.getData() == null) {
newIntent1.setData(sourceIntent.getData());
}
newIntent1.putExtras(parameters);
if(activity.getCallingActivity() != null) {
newIntent1.setFlags(33554432);
}
if(!AppKit.isAvailableIntent(newIntent1)) {
Log4a.e(TAG, new Object[]{"No registered route to handle uri:" + uri.toString()});
} else {
activity.startActivity(newIntent1);
}
}
}
}
}
}
5.具体使用:
第三方调用:
1.建立一个路由分发器,在Manifest中注册路由分发器的接收规则
2.路由分发器
这里作为一个路由分发的中转站,接收所有intent-filter中匹配的第三方 Web的请求,具体操作在上面的RouteDispatch中
public class RouteDispatchActivity extends AppCompatActivity {
public RouteDispatchActivity() {
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RouteDispatch.dispatch(this);
this.finish();
}
}