Android启动一个界面,可以通过显示和隐式两种方式。
(一)activity的跳转方式小结地址:https://github.com/buder-cp/base_component_learn/tree/master/URIJump
方式一:显示启动,通过类名一般应用内部跳转会经常使用该方法。
/**
* 方式一:类名跳转
*/
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intent);
方式二:通过ComponentName跳转
通过组件名称跳转需要知道包名和Activity名称,该方法一般用于外部应用跳转。
Intent it = new Intent();
ComponentName componentName = new ComponentName("com.test.helleworld", "com.test.helloworld.ActivityA");
it.setComponent(componentName);
startActivity(it);
方式三:通过包名、类名跳转
与上述方法类似,都需要知道包名和Activit名称,其实setClassNmae里面也是通过设置ComponentName的,该方法一般用于外部应用跳转。
Intent it = new Intent();
it.setClassName("com.test.helleworld", "com.test.helloworld.ActivityA");
startActivity(it);
方式四:根据包名跳转
根据应用包名跳转,这里打开的是跳转应用的默认启动Activity。
PackageManager pm = getPackageManager();
Intent it = pm.getLaunchIntentForPackage("com.test.helloworld");
//it.setAction("android.intent.action.MAIN");
startActivity(it);
方式五:隐式启动利用action,通过在AndroidManifest中定义intentfilter进行action的匹配
不需要指定跳转的Activity名字,只需双方协定好指定的action即可,该方法一般常用于外部应用跳转。
- 步骤一:在启动界面new Intent中定义好我们要跳转到界面的action,这个action名字可以随意起,例如这里是self_define_action
/**
* 方式二:action跳转
*/
Intent intent1 = new Intent("self_define_action");
startActivity(intent1);
- 步骤二:在被启动界面的manifest文件中定义好和上面对应的action
方式三:隐式启动,利用URI,和上面的action类似,只是这里由action转成了uri
- 步骤一:首先需要定义符合URI通信的协议,这里很简单:hello://test.uri.activity?action=123&secret=buder
(1)scheme协议:hello
(2)host路由地址:test.uri.activity
(3)?query参数:query参数可以有多个,是键值对的表示方式,键值对之间用&连接。本例中key=action,value=123
- 步骤二:协议定义好后,需要在intent中添加上action字段,这里我们还是自定义self_define_uri作为action字段
/**
* 方式三:URI跳转
*/
String uriString = "hello://test.uri.activity?action=123&secret=buder";
Uri uri = Uri.parse(uriString);
Intent intent = new Intent("self_define_uri");
//Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
- 步骤三:在被跳转的activity的manifest文件中声明好和上面两步对应的协议字段
本例中,action为self_define_uri;scheme为hello;host为test.uri.activity
- 步骤四:当我们业务中需要传过来的参数时,在接收方这么获取穿过来的参数:
Intent intent = getIntent();
if (null != intent) {
Uri uri = intent.getData();
if (uri == null) {
return;
}
String actionData = uri.getQueryParameter("action");
String secretData = uri.getQueryParameter("secret");
TextView tv = findViewById(R.id.txt);
tv.append("\n传过来的action值为:" + actionData);
tv.append("\n传过来的secret值为:" + secretData);
}
(二)activity传参小结
intent传递参数的方式有两种,一种是大家熟悉的extra,键值对的形式,直接传递参数;另一种就是uri的方式。
方式一:intent传参,将参数放到bundle中如下例子中,有一个playInfo的key里面有一个JSONObject的字符串:
Intent intent = new Intent(ACTION_DETAIL);
Bundle bundle = new Bundle();
JSONObject playInfoJsonObject = new JSONObject();
try {
playInfoJsonObject.put("playType", "");
playInfoJsonObject.put("videoId", content.related_aids);
playInfoJsonObject.put("episodeId", content.related_vids);
playInfoJsonObject.put("history", "-1");
playInfoJsonObject.put("chnId", "");
playInfoJsonObject.put("customer", PACKAGE_NAME);
} catch (JSONException e) {
e.printStackTrace();
}
String playInfo = playInfoJsonObject.toString();
bundle.putString("playInfo", playInfo);
intent.putExtras(bundle);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
方式二:使用URI,需要先拼接URI地址
先来认识下URI,如下这个字符串就是一个URI地址例子:
String str = "content://com.android.test?username=merlin&password=123456";
它的文件结构如下:
[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 等等……
对于URI,我们平时的用法如下:
Uri uri = Uri.parse("qijian://test.uri.activity?action=1");
Intent intent = new Intent("android.qijian.schemeurl.activity");
intent.setData(uri);
startActivity(intent);
有时候需要我们去拼装这些URI,常用代码如下:
public static Uri getRouteUri(Action action){
try {
Uri.Builder builder=new Uri.Builder();
builder.scheme(action.scheme);
builder.authority(action.host);
builder.path(action.path);
Map query=action.query;
if(query!=null&&!query.isEmpty()){
for (Map.Entry entry:query.entrySet()){
builder.appendQueryParameter(entry.getKey(), entry.getValue());
}
}
return builder.build();
} catch (Exception e) {
Log.e(TAG, "getRouteUri: build route uri error, action="+action, e);
return null;
}
}
(三)启动三方APP的方式小结
两种启动三方APP包的方式:
if (!TextUtils.isEmpty(packageName)) {
Intent intent;
if (!TextUtils.isEmpty(className)) {
ComponentName componentName = new ComponentName(packageName, className);
intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setComponent(componentName);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(CUSTOM_PARAMS, params);
} else {
intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
intent.putExtra(CUSTOM_PARAMS, params);
}
context.startActivity(intent);
}