URI(uniform resource identifier):统一资源标识符
URL(uniform resource locator):统一资源定位符
URN(uniform resource name):统一资源命名
接下来看一下URI的结构:
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]
path可以有多个,每个用/连接,比如:
scheme://authority/path1/path2/path3?query#fragment
query参数可以带有对应的值,也可以不带,如果带对应的值用=表示,如:
scheme://authority/path1/path2/path3?id = 1#fragment
query参数可以有多个,每个用&连接:
scheme://authority/path1/path2/path3?id=1&name=ming&old#fragment
接下来我们一个Android的实例:
//Manifest文件配置
<intent-filter>
<!--下面这几个必须要设置-->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!--协议部分-->
<data
android:host="test"
android:path="/page"
android:port="8080"
android:scheme="app" />
</intent-filter>
启动页面配置:
Uri uri = Uri.parse("app://test:8080/page?system=android&id=45464");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
接收页面配置:
Intent intent = getIntent();
String scheme = intent.getScheme();
String dataString = intent.getDataString();
Uri uri = intent.getData();
System.out.println("scheme=" + scheme);
System.out.println("dataString=" + dataString);
if (uri != null) {
//完整的url信息
String url = uri.toString();
//scheme部分
String schemes = uri.getScheme();
//host部分
String host = uri.getHost();
//port部分
int port = uri.getPort();
//访问路径
String path = uri.getPath();
//编码路径
String path1 = uri.getEncodedPath();
//query部分
String queryString = uri.getQuery();
//获取参数值
String system = uri.getQueryParameter("system");
String id = uri.getQueryParameter("id");
System.out.println("url=" + url);
System.out.println("schemes=" + schemes);
System.out.println("host=" + host);
System.out.println("port=" + port);
System.out.println("path=" + path);
System.out.println("path1=" + path1);
System.out.println("queryString=" + queryString);
System.out.println("system=" + system);
System.out.println("id=" + id);
}
最终看一下执行结果:
scheme=app
dataString=app://test:8080/page?system=android&id=45464
url=app://test:8080/page?system=android&id=45464
schemes=app
host=test
port=8080
path=/page
path1=/page
queryString=system=android&id=45464
system=android
id=45464
接下来有两个问题简明说一下:
1、使用自定义的URL启动Activity时,默认是以FLAG_ACTIVITY_NEW_TASK的方式启动的,所以可能存在URL启动的Activity跟应用已启动的Activity不再同一个堆栈的现象。
方案:这种情况下,需要在manifest中将Activity多配置一个taskAffinity属性,约束URL启动的Activity与应用自身的启动的Activity在同一个堆栈中。
2、应用A使用url的方式唤起应用B的Activity时,可能存在应用B的Activity启动了,但是堆栈仍然在后台的现象,即应用B的Activity没有聚焦的问题。
方案:这种情况下,应用B的Activity收到启动的请求后,可以主动将Activity对应的堆栈移动到最前端,需要在manifest中申请android.permission.REORDER_TASKS权限。
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(), am.MOVE_TASK_WITH_HOME);