Android中的Scheme是一种页面跳转协议,和网站通过URL的形式访问一样,APP同样可以通过这种方式进行跳转,它可以很方便的满足我们在一些场景中的需求:
- 当应用接收到Push,点击通知栏消息跳转到特定页面,比如商品详情等。
- 通过服务器下发的跳转路径,客户端可以根据路径跳转相应页面。
- 应用跳转到其他APP指定页面。
- H5页面点击锚点,APP端跳转具体页面。
关于URL,URI,Uri
-
URL:Uniform Resource Locator,通用资源定位符;
所属:
import java.net.URL;
URL是一种资源定位器和根据协议建立的约束规则与资源通信的读写机制,用于定位、读写资源。
-
URI:Uniform Resource Identifier,通用资源标识符;
所属:
import java.net.URI;
URI仅仅是资源名称,知道了URI最多就是知道有这么一个名称的资源,也就是说URI只能定位资源。
-
Uri:Universal Resource Identifier,通用资源标识符(同URI);
所属:
import android.net.Uri;
Uri是URI的“扩展”以适应Android系统的需要,Uri类是一个不可改变的URI引用,包括一个URI和一些碎片,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。
URI是一种更广的定义,而URL则是URI的一个子集,就是说URL是URI的一部分,换句话说,每个URL都是URI,但是不是每个URI都是URL的。同样属于URI子集的还有一个URN。
在Android中我们使用Uri
Uri
-
结构
[scheme:]scheme-specific-part[#fragment]
进一步划分:
[scheme:][//authority][path][?query][#fragment]
- path可以有多个,每个用/连接,比如
scheme://authority/path1/path2/path3?query#fragment - query参数可以带有对应的值,也可以不带,如果带对应的值用=表示,如:
scheme://authority/path1/path2/path3?id = 1#fragment,这里有一个参数id,它的值是1 - query参数可以有多个,每个用&连接
scheme://authority/path1/path2/path3?id = 1&name = mingming&old#fragment
这里有三个参数:
参数1:id,其值是:1
参数2:name,其值是:mingming
参数3:old,没有对它赋值,所以它的值是null - 在android中,除了scheme、authority是必须要有的,其它的几个path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变,比如:
其中"path"可不要:scheme://authority?query#fragment
其中"path"和"query"可都不要:scheme://authority#fragment
其中"query"和"fragment"可都不要:scheme://authority/path
"path","query","fragment"都不要:scheme://authority
上边的解释是抄来的
出处在此
Scheme怎么用
模拟点击链接获得链接中的参数
AndroidManifest中设置增加拦截器(intent-filter),设置scheme
<activity
android:name=".SchemeActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!--够被浏览器安全使用的 activitie 必须支持这个类别 此Demo中非必须-->
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="chicha" />
</intent-filter>
</activity>
设置链接
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scheme)
scheme_tvnodata.text = Html.fromHtml("<a href='chicha://domain/path?params'>CLICK THIS NODATA</a>")
//激活链接
scheme_tvnodata.movementMethod = LinkMovementMethod.getInstance()
scheme_tvdata.text = Html.fromHtml("<a href='chicha://scheme_activity?type=0&buffer=这是个字符串'>CLICK THIS DATA</a>")
scheme_tvdata.movementMethod = LinkMovementMethod.getInstance()
}
}
在SchemeActivity中通过重写onNewIntent方法获取参数
/**
* 为了避免多次实例化这里我们使用onNewIntent
*/
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val uri = intent?.data
if (uri != null) {
// 完整的url信息
val url = uri.toString()
Log.e(TAG, "url: $uri")
// scheme部分
val scheme = uri.scheme
Log.e(TAG, "scheme: $scheme")
// host部分
val host = uri.host
Log.e(TAG, "host: $host")
//port部分
val port = uri.port
Log.e(TAG, "port: $port")
// 访问路劲
val path = uri.path
Log.e(TAG, "path: $path")
// Query部分
val query = uri.query
Log.e(TAG, "query: $query")
//获取指定参数值
val type = uri.getQueryParameter("type")
Log.e(TAG, "type: $type")
val buffer = uri.getQueryParameter("buffer")
Log.e(TAG, "buffer: $buffer")
}
}
Log如下:
09-10 23:03:19.547 31722-31722/com.vayne.firstkotlintest E/BaseActivity: ------SchemeActivity
09-10 23:03:21.749 31722-31722/com.vayne.firstkotlintest E/SchemeActivity:
url: chicha://scheme_activity?type=0&buffer=这是个字符串
scheme: chicha
host: scheme_activity
port: -1
path:
09-10 23:03:21.750 31722-31722/com.vayne.firstkotlintest E/SchemeActivity:
query: type=0&buffer=这是个字符串
type: 0
09-10 23:03:21.751 31722-31722/com.vayne.firstkotlintest E/SchemeActivity:
buffer: 这是个字符串
服务器下发路径
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("chicha://domain/path?params")));
这里的”chicha://domain/path?params”就是服务器下发的跳转路径,当我们执行startActivity的时候就会调起SchemeActivity,然后我们通过在SchemeActivity解析scheme的内容,跳转相应的页面。
网友评论