├── .gitignore ├── LICENSE.txt ├── README.md ├── build.gradle ├── demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── netease │ │ └── heartouch │ │ └── example │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── netease │ │ │ └── hearttouch │ │ │ └── example │ │ │ ├── HTApplication.java │ │ │ ├── MainActivity.java │ │ │ ├── PayActivity.java │ │ │ ├── ProductDetailActivity.java │ │ │ └── WebActivity.java │ └── res │ │ ├── anim │ │ ├── enter.xml │ │ ├── enter1.xml │ │ └── exit.xml │ │ ├── layout │ │ ├── activity_pay.xml │ │ ├── activity_product_detail.xml │ │ ├── activity_web.xml │ │ ├── content_pay.xml │ │ ├── content_product_detail.xml │ │ └── content_web.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── netease │ └── heartouch │ └── example │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── htrouterdispatch-process ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── netease │ └── hearttouch │ └── router │ ├── HTAnnotatedClass.java │ ├── HTClassValidator.java │ ├── HTCodeGenerator.java │ └── HTRouterDispatchProcess.java ├── htrouterdispatch ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── netease │ └── hearttouch │ └── router │ ├── HTRouter.java │ └── HTRouterEntry.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | local.properties 3 | 4 | .idea/ 5 | 6 | .gradle/ 7 | *.iml 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Netease Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HT Universal Router页面管理框架 2 | `HT Universal Router`是一种基于注解的Android页面管理框架,通过URL进行页面跳转管理,同时可以设置进入及退出动画,并提供页面降级及跳转拦截和重定向功能。 3 | ## 基本功能 4 | - 通过`URL`进行`Activity`之间跳转 5 | - 参数传递 (复杂类型参数传递) 6 | - 进入退出动画资源自定义 7 | - 页面降级 (注: 降级指的是`Native`无法匹配的`URL`可以转为通过`Webview`处理) 8 | - `Webview`跳转`Native`识别 9 | - `URL`中参数自动转化`Intent`参数 10 | - 支持`startActivity`和`startActivityForResult` 11 | - `URL`与`Activity`多对一映射 12 | - 支持`Debug`模式,日志输出 13 | - 支持适配Android M DeepLink 14 | - 支持全局跳转数据,处理每次跳转监听 用户打点统计等功能 15 | - 支持自定义`WebActivity`接收`URL`的`KEY` 16 | 17 | ## 用法 18 | 19 | ### AndroidManifest.xml 20 | 添加权限: 21 | 22 | ``` 23 | 24 | ``` 25 | 注册`HTRouterActivity`,根据实际修改`data`标签中的信息 26 | 27 | ``` 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | ``` 41 | 相应的降级`WebActivity`,定义示例见后文。 42 | 43 | ``` 44 | 48 | ``` 49 | 50 | ### 初始化 51 | 在`Application`的`onCreate()`中添加如下信息,其中`HTRouterActivity`、`HTLogUtil`、`HTRouterManager`、`HTRouterHandler`、`HTRouterHandlerParams`编译后会自动生成(注:仅当有页面使用`@HTRouter`注解时,以上代码才会生成)。 52 | 53 | - 降级页面接收的`URL`的`key` 54 | - 注册降级页面相应的`WebviewActivity`; 55 | - 是否开启`debug`模式 56 | - 每次跳转的监听,可以进行自定义处理,包括跳转的拦截和重定义等,可以作为拦截器使用,通过返回true来阻止本管理框架进行跳转,通过修改`HTRouterHandlerParams`中的内容来修改跳转的目标。 57 | 58 | ``` 59 | HTRouterManager.init(); 60 | //注册绑定默认的降级页面 61 | StringcustomUrlKey = "customUrlKey"; //HTWebActivity接收参数key 62 | HTRouterManager.registerWebActivity(WebActivity.class, customUrlKey); 63 | //开启Debug模式,输出相应日志 64 | HTRouterManager.setDebugMode(true); 65 | HTRouterManager.setHtRouterHandler(new HTRouterHandler() { 66 | @Override 67 | public boolean handleRoute(Context context, HTRouterHandlerParams routerParams) { 68 | HTLogUtil.d("统计数据:" + context.getClass().getSimpleName() + "-->跳转url-->" + routerParams.url + " 参数intent" + routerParams.sourceIntent); 69 | //如果需要拦截或者改变跳转的目标可以直接改变url或者sourceIntent 70 | routerParams.url = "http://www.kaola.com/pay"; 71 | //如果返回true则表示由监听中进行处理,不需要HTRouter负责跳转 72 | return false; 73 | } 74 | }); 75 | 76 | ``` 77 | 78 | ### 注解使用 79 | `@HTRouter` 字段支持`Activity`类注解: 80 | 81 | - `url`: 支持url数组 {"http://kaola.com","http://m.kaola.com"} 82 | - `entryAnim` :`activity`进入动画 `R.anim.entry` 83 | - `exitAnim` :`activity`退出动画 `R.anim.exit` 84 | 85 | 例如: 86 | 87 | ``` 88 | @HTRouter(url = {"http://www.kaola.com/pay"},entryAnim = R.anim.enter,exitAnim = R.anim.exit) 89 | ``` 90 | 91 | ### 页面跳转方法 92 | 1. 使用`HTRouterManager.startActivity()`接口 93 | 94 | - `activity`: 当前页面的`activity` 95 | - `url`: 跳转的目标URL 96 | - `sourceIntent`: 传递进来一个intent,用于传递用户数据及启动模式等扩展 97 | - `isFinish`: 跳转后是否需要关闭当前页面 98 | 99 | 例如`HTRouterManager.startActivity(this, "http://www.kaola.com/pay", null, false);` 100 | 101 | 2. 还提供`HTRouterManager.startActivityForResult()`,参数与`HTRouterManager.startActivity()`相同,回调发生在`Activity`中。 102 | 3. 由于`Fragment`的`startActivityForResult()`的回调可以选择发生在`Fragment`或者`Fragment`所处的`Activity`中(通常直接调用`startActivityForResult()`发生在`fragment`中,而通过`getActivity().startActivityForResult()`则发生在Activity中),故另外提供`HTRouterManager.startActivityForResult(Fragment fragment, String url, Intent sourceIntent, boolean isFinish)`接口,该方法只有第一个参数不同。 103 | 104 | ### 参数获取 105 | 除了在页面跳转的`sourceIntent`中传入的自定义类型参数外,本框架还实现`URL`中参数字段的自动解析,解析后保存在`HashMap`中序列化后放在跳转的`Intent`参数中。用户可以用如下方式获取,需要进行强制类型转换: 106 | 107 | ``` 108 | Intent intent = getIntent(); 109 | HashMap urlParamsMap = (HashMap)intent.getSerializableExtra(HTRouterManager.HT_URL_PARAMS_KEY); 110 | ``` 111 | 112 | ### 降级及升级WebActivity示例 113 | * 降级`WebActivity`,`Native`处理不了的转`Webview`,只需要接收`url`参数后`loadUrl`一下。 114 | 115 | ``` 116 | public class WebActivity extends AppCompatActivity { 117 | @Override 118 | protected void onCreate(Bundle savedInstanceState) { 119 | super.onCreate(savedInstanceState); 120 | Intent intent = getIntent(); 121 | String url = intent.getStringExtra("customUrlKey"); 122 | WebView webView = new WebView(this); 123 | webView.getSettings().setJavaScriptEnabled(true); 124 | webView.getSettings().setUseWideViewPort(true); 125 | webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); 126 | webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); 127 | webView.getSettings().setLoadWithOverviewMode(true); 128 | String targetUrl = HTRouterManager.getHttpSchemaHostAndPath(url); 129 | HTLogUtil.d("打开链接=" + targetUrl); 130 | webView.loadUrl(targetUrl); 131 | setContentView(webView); 132 | } 133 | } 134 | ``` 135 | 136 | * 升级`WebActivity`,`webview`中的`url`先交给`native`处理,需要重载`shouldOverrideUrlLoading()`,处理`webview`中的`url`。 137 | 138 | ``` 139 | public class WebActivity extends AppCompatActivity { 140 | @Override 141 | protected void onCreate(Bundle savedInstanceState) { 142 | super.onCreate(savedInstanceState); 143 | //... 144 | //一些初始化... 145 | webView.setWebViewClient(new WebViewClient() { 146 | @Override 147 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 148 | Log.i("HT", "重新加载=" + url); 149 | HTRouterEntry entity = HTRouterManager.findRouterEntryByUrl(url); 150 | //为了防止匹配不上后循环跳,这里需要有个判断 151 | if (entity != null) { 152 | //匹配上之后 153 | HTRouterManager.startActivity(WebActivity.this, url, null, false); 154 | return true; 155 | } 156 | return super.shouldOverrideUrlLoading(view, url); 157 | } 158 | }); 159 | //... 160 | //一些后续操作 161 | } 162 | } 163 | ``` 164 | 165 | ### 进阶使用 166 | 本框架可以注册`HTRouterHandler`,进行跳转拦截或记录等处理,实现该接口并通过`HTRouterManager.setHtRouterHandler()`注册。返回值`true`代表拦截处理,则本框架不会进行后续的处理。返回`false`代表还需要本框架进行进一步跳转处理,同时可以修改`routerParams`中的`url`和`sourceIntent`来达到动态控制跳转的重定向。 167 | 168 | ``` 169 | public interface HTRouterHandler { 170 | boolean handleRoute(Context context, HTRouterHandlerParams routerParams); 171 | } 172 | ``` 173 | ## 集成 174 | ### Gradle 175 | `app`的`build.grade`中添加 176 | 177 | ``` 178 | apply plugin: 'com.neenbedankt.android-apt' 179 | 180 | dependencies { 181 | compile 'com.netease.hearttouch:ht-universalrouter-dispatch:0.1.0' 182 | apt 'com.netease.hearttouch:ht-universalrouter-dispatch-process:0.1.0' 183 | } 184 | ``` 185 | 186 | `project`的`build.gradle`的`dependencies`下面添加 187 | 188 | ``` 189 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' 190 | ``` 191 | 192 | ### maven 193 | ``` 194 | 195 | 196 | com.netease.hearttouch 197 | ht-universalrouter-dispatch 198 | 0.1.0 199 | 200 | 201 | com.netease.hearttouch 202 | ht-universalrouter-dispatch-process 203 | 0.1.0 204 | true 205 | 206 | 207 | ``` 208 | ## 代码混淆 209 | 如果要使用混淆,在引用工程的`proguard`文件中,添加如下代码: 210 | 211 | ``` 212 | -keep class com.netease.hearttouch.router.** { *; } 213 | ``` 214 | 215 | ## 许可证 216 | `HT Universal Router` 使用 `MIT` 许可证,详情见 [LICENSE](https://github.com/NEYouFan/ht-universalrouter-android/blob/master/LICENSE.txt) 文件。 -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.5.0' 9 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.neenbedankt.android-apt' 3 | 4 | android { 5 | compileSdkVersion 23 6 | buildToolsVersion "23.0.2" 7 | 8 | defaultConfig { 9 | applicationId "com.netease.heartouch.example" 10 | minSdkVersion 14 11 | targetSdkVersion 23 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | buildTypes { 16 | debug { 17 | minifyEnabled true 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | 21 | release { 22 | minifyEnabled true 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | compile fileTree(dir: 'libs', include: ['*.jar']) 30 | testCompile 'junit:junit:4.12' 31 | compile 'com.android.support:appcompat-v7:23.1.1' 32 | compile 'com.android.support:design:23.1.1' 33 | } 34 | 35 | dependencies { 36 | compile project(':htrouterdispatch') 37 | apt project(':htrouterdispatch-process') 38 | } -------------------------------------------------------------------------------- /demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\UserSpace\Android\AndroidSDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -keep class com.netease.heartouch.router.** { *; } 19 | -dontwarn okio.** -------------------------------------------------------------------------------- /demo/src/androidTest/java/com/netease/heartouch/example/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.netease.heartouch.example; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 44 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /demo/src/main/java/com/netease/hearttouch/example/HTApplication.java: -------------------------------------------------------------------------------- 1 | package com.netease.hearttouch.example; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | import com.netease.hearttouch.router.HTLogUtil; 7 | import com.netease.hearttouch.router.HTRouterHandler; 8 | import com.netease.hearttouch.router.HTRouterHandlerParams; 9 | import com.netease.hearttouch.router.HTRouterManager; 10 | 11 | /** 12 | * @author hzshengxueming 13 | */ 14 | 15 | public class HTApplication extends Application { 16 | @Override 17 | public void onCreate() { 18 | super.onCreate(); 19 | HTRouterManager.init(); 20 | //注册绑定默认的降级页面 21 | String customUrlKey = "customUrlKey"; //HTWebActivity接收参数key 22 | HTRouterManager.registerWebActivity(WebActivity.class, customUrlKey); 23 | //开启Debug模式,输出相应日志 24 | HTRouterManager.setDebugMode(true); 25 | //处理每次跳转监听 用户打点统计等 26 | HTRouterManager.setHtRouterHandler(new HTRouterHandler() { 27 | @Override 28 | public boolean handleRoute(Context context, HTRouterHandlerParams routerParams) { 29 | HTLogUtil.d("统计数据:" + context.getClass().getSimpleName() + "-->跳转url-->" + routerParams.url + " 参数intent" + routerParams.sourceIntent); 30 | //如果需要拦截或者改变跳转的目标可以直接改变url或者sourceIntent 31 | // routerParams.url = "http://www.kaola.com/pay?a=b&c=d"; 32 | //如果返回true则表示由监听中进行处理,不需要HTRouter负责跳转 33 | return false; 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/main/java/com/netease/hearttouch/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.netease.hearttouch.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.Button; 7 | 8 | import com.netease.hearttouch.router.HTRouter; 9 | import com.netease.hearttouch.router.HTRouterManager; 10 | 11 | @HTRouter(url = {"kaola://www.kaola.com/","kaola://m.kaola.com"},entryAnim = R.anim.enter,exitAnim = R.anim.exit) 12 | public class MainActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | Button button = new Button(this); 18 | button.setText("跳转到考拉商品类别H5页面"); 19 | button.setOnClickListener(new View.OnClickListener() { 20 | @Override 21 | public void onClick(View v) { 22 | HTRouterManager.startActivity(MainActivity.this, "http://www.kaola.com/activity/detail/6932.shtml?navindex=7", null, true); 23 | } 24 | }); 25 | setContentView(button); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/java/com/netease/hearttouch/example/PayActivity.java: -------------------------------------------------------------------------------- 1 | package com.netease.hearttouch.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.Button; 7 | 8 | import com.netease.hearttouch.router.HTRouter; 9 | 10 | @HTRouter(url = {"http://www.kaola.com/pay"}, entryAnim = R.anim.enter, exitAnim = R.anim.exit) 11 | public class PayActivity extends AppCompatActivity { 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_pay); 17 | Button button = (Button) findViewById(R.id.id_close_pay_page); 18 | button.setOnClickListener(new View.OnClickListener() { 19 | @Override 20 | public void onClick(View v) { 21 | finish(); 22 | } 23 | }); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/main/java/com/netease/hearttouch/example/ProductDetailActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.netease.hearttouch.example; 3 | 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.webkit.WebSettings; 10 | import android.webkit.WebView; 11 | import android.webkit.WebViewClient; 12 | import android.widget.Button; 13 | import android.widget.TextView; 14 | import android.widget.Toast; 15 | 16 | import com.netease.hearttouch.router.HTRouter; 17 | import com.netease.hearttouch.router.HTRouterEntry; 18 | import com.netease.hearttouch.router.HTRouterManager; 19 | 20 | import java.util.HashMap; 21 | 22 | @HTRouter(url = {"http://www.kaola.com/activity/detail/{id}.shtml","http://m.kaola.com/activity/detail/{id}.shtml","http://m.kaola.com/product/{id}.html","http://www.kaola.com/product/{id}.html"},entryAnim = R.anim.enter,exitAnim = R.anim.exit) 23 | public class ProductDetailActivity extends AppCompatActivity implements View.OnClickListener{ 24 | private TextView tv; 25 | private Button btn; 26 | private Button btn1; 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_product_detail); 31 | 32 | 33 | tv = (TextView) findViewById(R.id.tv); 34 | btn= (Button) findViewById(R.id.btn); 35 | btn.setOnClickListener(this); 36 | btn1 = (Button) findViewById(R.id.btn1); 37 | btn1.setOnClickListener(this); 38 | WebView webView = (WebView) findViewById(R.id.webview); 39 | 40 | //获取URL参数 41 | Intent intent = getIntent(); 42 | HashMap urlParamsMap = (HashMap)intent.getSerializableExtra(HTRouterManager.HT_URL_PARAMS_KEY); 43 | for(String key : urlParamsMap.keySet()){ 44 | Log.d("url_params", key + ":" + urlParamsMap.get(key)); 45 | } 46 | 47 | webView.getSettings().setJavaScriptEnabled(true); 48 | webView.getSettings().setUseWideViewPort(true); 49 | webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); 50 | webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); 51 | webView.getSettings().setUseWideViewPort(true); 52 | webView.getSettings().setLoadWithOverviewMode(true); 53 | webView.setWebViewClient(new WebViewClient() { 54 | @Override 55 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 56 | Log.i("HT", "重新加载=" + url); 57 | HTRouterEntry entity = HTRouterManager.findRouterEntryByUrl(url); 58 | //为了防止匹配不上后循环跳,这里需要有个判断 59 | if (entity != null) { 60 | HTRouterManager.startActivity(ProductDetailActivity.this, url, null, false); 61 | return true; 62 | } 63 | return super.shouldOverrideUrlLoading(view, url); 64 | } 65 | }); 66 | if (intent!=null){ 67 | Log.i("HT", "产品详情=" + intent.getData()); 68 | tv.setText("产品详情=" + intent.getData()); 69 | HTRouterEntry entity = HTRouterManager.findRouterEntryByUrl(intent.getData().toString()); 70 | webView.loadUrl(intent.getData().toString()); 71 | } 72 | 73 | 74 | } 75 | 76 | @Override 77 | public void onClick(View v) { 78 | switch (v.getId()){ 79 | case R.id.btn: 80 | Intent sourceIntent = new Intent(); 81 | sourceIntent.putExtra("price",12345); 82 | sourceIntent.putExtra("id","m123456"); 83 | sourceIntent.putExtra("name","Mac Pro 13寸"); 84 | HTRouterManager.startActivityForResult(ProductDetailActivity.this,"http://www.kaola.com/pay",sourceIntent,false,1001); 85 | break; 86 | case R.id.btn1: 87 | Intent sourceIntent1 = new Intent(); 88 | sourceIntent1.putExtra("price",12345); 89 | sourceIntent1.putExtra("id","m123456"); 90 | sourceIntent1.putExtra("name","Mac Pro 13寸"); 91 | HTRouterManager.startActivityForResult(ProductDetailActivity.this, 92 | "http://www.kaola.com/mall/paygame.html", 93 | sourceIntent1, false, 1001); 94 | break; 95 | } 96 | } 97 | 98 | @Override 99 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 100 | switch (requestCode){ 101 | case 1001: 102 | Toast.makeText(ProductDetailActivity.this,"支付返回",Toast.LENGTH_SHORT).show(); 103 | break; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /demo/src/main/java/com/netease/hearttouch/example/WebActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.netease.hearttouch.example; 3 | 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.webkit.WebSettings; 9 | import android.webkit.WebView; 10 | import android.webkit.WebViewClient; 11 | 12 | import com.netease.hearttouch.router.HTLogUtil; 13 | import com.netease.hearttouch.router.HTRouterEntry; 14 | import com.netease.hearttouch.router.HTRouterManager; 15 | 16 | public class WebActivity extends AppCompatActivity { 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | Intent intent = getIntent(); 22 | String url = intent.getStringExtra("customUrlKey"); 23 | WebView webView = new WebView(this); 24 | webView.getSettings().setJavaScriptEnabled(true); 25 | webView.getSettings().setUseWideViewPort(true); 26 | webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); 27 | webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); 28 | webView.getSettings().setUseWideViewPort(true); 29 | webView.getSettings().setLoadWithOverviewMode(true); 30 | webView.setWebViewClient(new WebViewClient() { 31 | @Override 32 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 33 | Log.i("HT", "重新加载=" + url); 34 | HTRouterEntry entity = HTRouterManager.findRouterEntryByUrl(url); 35 | //为了防止匹配不上后循环跳,这里需要有个判断 36 | if (entity != null) { 37 | HTRouterManager.startActivity(WebActivity.this, url, null, false); 38 | return true; 39 | } 40 | return super.shouldOverrideUrlLoading(view, url); 41 | } 42 | }); 43 | String targetUrl = HTRouterManager.getHttpSchemaHostAndPath(url); 44 | HTLogUtil.d("打开链接=" + targetUrl); 45 | webView.loadUrl(targetUrl); 46 | setContentView(webView); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/enter.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/enter1.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/exit.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_pay.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_product_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/content_pay.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 19 |