Android基础笔记(七)-页面跳转和数据传递
Activity简介
Activity是Android的四大组件之一,它用于展示界面。它提供一个屏幕,用户可以用来交互,可以通过setContentView(View)
来显示指定的控件。
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent
进行通信。
Activity的简单使用
① 定义类继承Activity
- ② 在AndroidManifest.xml的
<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>
- Activity在清单文件中的配置
- ①Lable属性:Activity页面的标题,界面的名字,如果此界面被创建快捷方式,则快捷方式的名字就是lable值。
- ②Name属性:指定的值为:包名.Activity类名。包名如果与mainfest的package一致,可以用“.”代替;或者不写。
- ③Intent-filter子节点:添加意图过滤,可以通过隐式意图启动。可以在桌面生成快捷方式,增加应用程序的入口。
- ④Icon属性:指定应用程序的图标
- ⑤android:theme属性:指定主题android:theme=”@android:style/Theme.Dialog”
- 如何让程序有多个启动入口
-
创建一个
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
。
Activity之间的跳转
- 什么是意图?
- 即Intent,用于激活组件,Android的组件都可以通过intent去激活。
- Activity之间的跳转分为两种
-
①显式意图跳转:知道跳转目标的类名,并且可以拿到其字节码对象。一般用于自己程序的内部。一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。
//创建一个Intent对象,并传递当前对象(Context对象)和要跳转的Activity类字节码 Intent intent = new Intent(this, SecondActivity.class); //启动第二个Activity startActivity(intent);
- ②隐式意图跳转::可以在当前程序跳转到另一个程序的页面。隐式跳转不需要引用到那个类,但是必须得知道那个界面的动作(action)和信息(category);因此,能够被隐式跳转的Activity,在清单文件中声明时必须指定动作和信息这两个属性。
- 显式意图是指在创建意图时指定了组件,而隐式意图则不指定组件,通过动作、类型、数据匹配对应的组件。
-
当我们为一个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传递过多的数据,会影响到应用程序的使用。
- 使用意图过滤器数据协议传递数据
- 设置数据协议和配置数据的mimeType,从而达到传递数据的目的
-
① 在清单文件中配置意图过滤器
<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);
- 使用意图的Bundle传递数据
-
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");
创建Activity获取返回数据
- 操作步骤:
- ①使用
startActivityForResult(Intent intent, int requestCode)
方法打开Activity - ②重写
onActivityResult(int requestCode, int resultCode, Intent data)
方法 - ③在被打开的Activity中调用
setResult(int resultCode, Intent data)
设置返回数据之后,使用finish()
关闭Activity,第一个Activity就会调用onActivityResult
方法 - requestCode,请求码:用于区别是哪个操作启动的意图
- resultCode,结果码,用于区别是哪个Activity返回的数据
如何调用系统发送短信的页面
如何能够把我们的数据传递给系统的短信页面,例如下面这个样子
代码其实是很简单的
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值怎么找到?其实才是个难点。
- 接下来就讲一下如何找到这些关键信息的思路。当前,前提是你要有Android的源码。
- ①我们知道,Andriod有4层架构,最上层是应用层,在原生的系统中就带有很多的应用,而短息也是应用之一。在我们的源码中,可以知道
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
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。