Activity是Android的四大组件之一,它用于展示界面。它提供一个屏幕,用户可以用来交互,可以通过setContentView(View)
来显示指定的控件。
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent
进行通信。
① 定义类继承Activity
<application>
节点中声明
<activity>
<application>
:中lable是指程序的名字,在卸载页面显示的名字就是这个lable指定的。
☆<activity>
中的lable是指activity的名字,如果此activity还指定了以下intent-filter
,那么这个界面就会在桌面创建快捷方式,快捷方式名字就是这个activity的lable。
<category>
:指定意图的类别,LAUNCHER
是在桌面创建快捷方式。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
创建一个SecondActivity
并在清单文件中声明,且修改两个<activity>
的android:label
值。
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
<activity android:name="com.bzh.launch.MainActivity" android:label="我是入口1" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.bzh.launch.SecondActivity" android:label="我是入口2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
测试结果图如下:
我们可以看到,在应用程序清单中多了两个应用图标我是入口1
和我是入口2
,分别打开后所对应的就是清单文件中声明的Activity
。
①显式意图跳转:知道跳转目标的类名,并且可以拿到其字节码对象。一般用于自己程序的内部。一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。
//创建一个Intent对象,并传递当前对象(Context对象)和要跳转的Activity类字节码
Intent intent = new Intent(this, SecondActivity.class);
//启动第二个Activity
startActivity(intent);
当我们为一个Activity增加如下的过滤器时,
<intent-filter >
<!-- 在意图过滤器中设置action和category,当有匹配的action和category的时候启动该Activity。这里使用Android提供的默认category即可 -->
<action android:name="com.itheima.activitySkip.SecondActivity"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
那么想要激活这个Activity的话,需要在intent
中指定动作和类型
//创建一个Intent对象
Intent intent = new Intent();
//设置Action
intent.setAction("com.bzh.SecondActivity");
//对于android.intent.category.DEFAULT类型的信息为Android系统默认的信息,省略也可以
intent.addCategory("android.intent.category.DEFAULT");
//启动Activity
startActivity(intent);
Intent除了可以激活组件(启动Activity等),还可以通过封装的Bundle对象来携带数据。所以在启动一个Activity的时候,同时还可以传递数据,然后在新的Activity中可以获得意图对象以获取其中Bundle保存的数据。
Intent可传递的数据类型有: 八大基本数据类型,String,数组,ArrayList<String>
, Bundle数据捆, 实现序列化接口的javabean。
实现Serizlizable可以再网络中传输
实现Parcelable可以序列化到内存中
注意: Intent传递的数据过多可能会造成跳转速度极慢甚至黑屏一会,不要用Intent传递过多的数据,会影响到应用程序的使用。
① 在清单文件中配置意图过滤器
<activity android:name="com.bzh.SecondActivity">
<!-- 配置意图过滤器 -->
<intent-filter >
<!-- 在意图过滤器中设置action和category,当有匹配的action和category的时候启动该Activity -->
<action android:name="com.bzh.SecondActivity"/>
<!-- 设置数据协议 -->
<data android:scheme="money"/>
<!-- 配置数据的mimeType:必须为xxx/xxx的格式,否则会报异常 -->
<data android:mimeType="data/mymime"/>
</intent-filter>
</activity>
② 在FristActivity
中启用意图,并使用数据协议,设置数据。
// 创建一个Intent对象
Intent intent = new Intent();
// 设置Action
intent.setAction("com.bzh.SecondActivity");
// 对于android.intent.category.DEFAULT类型的信息为Android系统默认的信息,省略也可以
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.parse("money:转账100元。"), "data/mymime");
③ 在SecondActivity
中使用getIntent()
获取到意图,并拿到数据
//获取从当前Context对象中获取Intent
Intent intent = getIntent();//注意这个是getIntent()
//获取数据
String data = intent.getData().toString();
System.out.println(data);
Google在Intent中提供了大量的重载的putExtra(XX,XX)
方法,帮助我们传递数据,但是我们看一下源码会发现底层用的都是Bundle
对象来实现的。
public Intent putExtra(String name, char[] value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putCharArray(name, value);
return this;
}
我们再看一下Bundle
的构造函数,发现Bundle内部其实是个Map
public Bundle() {
mMap = new HashMap<String, Object>();
mClassLoader = getClass().getClassLoader();
}
Intent
中如何借助
Bundle
传递数据
在发送端
//给Intent设置数据
intent.putExtra("name", "张三");
//给你Intent设置字符串类型的集合
intent.putStringArrayListExtra("list", list);
//声明一个Bundle对象,bundle内部是包装过的map集合
Bundle bundle = new Bundle();
//在Bundle对象中绑定数据
bundle.putString("pwd", "123456");
//给Intent设置Bundle对象
intent.putExtras(bundle);//通过putExtras()传递bundle
接收端
Bundle extras = intent.getExtras();//通过getExtras获取bundle
//从Bundle中获取可以为name的数据
String name = (String) extras.get("name");//再通过get()获取具体值
System.out.println("name="+name);
//从Bundle对象中获取key为pwd的数据
String pwd = (String) extras.get("pwd");
System.out.println(pwd);
//从Bundle中获取ley为list的数据
List<String> list = (List<String>) extras.get("list");
startActivityForResult(Intent intent, int requestCode)
方法打开Activity
onActivityResult(int requestCode, int resultCode, Intent data)
方法
setResult(int resultCode, Intent data)
设置返回数据之后,使用
finish()
关闭Activity,第一个Activity就会调用
onActivityResult
方法
如何能够把我们的数据传递给系统的短信页面,例如下面这个样子
代码其实是很简单的
Intent intent = new Intent();
// 设置发送短信的动作
intent.setAction("android.intent.action.SEND");
intent.addCategory("android.intent.category.DEFAULT");
// 设置数据类型
intent.setType("text/plain");
// 使用Bundle传递数据
intent.putExtra("sms_body", content);
startActivity(intent);
但是里面有些关键信息(意图过滤器,键值),例如action、type、putExtra的key值怎么找到?其实才是个难点。
android4.4src/packages/apps
就是我们系统自带的一些应用。
android4.4src/pagkages/apps/mms/
③ 我们知道,清单文件中的activity下才是定义意图过滤器的地方,所以我们看一下清单文件,而且,既然是发送短信,我们再搜索一下SEND
关键字,可以得到如下的结果:
<activity android:name=".ui.ComposeMessageActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:windowSoftInputMode="stateHidden|adjustResize" android:theme="@style/MmsHoloTheme" android:parentActivityName=".ui.ConversationList" android:launchMode="singleTop" >
...
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
...
</activity>
这样,意图过滤器的关键信息就知道了;接下来就是要在Bundle
中保存数据了,那么intent.putExtras(K,V)
中的K值怎找到?
既然这个是系统的应用,那么系统的代码中就应该会有类似于intent.putExtras(K,V)
这样的代码,而上面的<activity name='...'>
中的name属性值为.ui.ComposeMessageActivity
,我们又知道了具体的类是什么,那么我们搜索一下就OK了。结果如下:
发送短信的步骤相当简单,请参看下面的代码:
// 获取短信管理器
SmsManager smsManager = SmsManager.getDefault();
// 防止短信内容过长,将其内容分割开
ArrayList<String> messageList = smsManager.divideMessage(content);
for (String sms : messageList) {
// 目标人
String destinationAddress = contact;
// 短信服务中心地址
String scAddress = null;
// 短信内容
String text = sms;
// 延期广播一般为NULL
PendingIntent sentIntent = null;
PendingIntent deliveryIntent = null;
// 使用短信管理器发送短信
smsManager.sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
}
当然,这只是很简单的示例,更为详细的请参看Android API