当前位置: 代码迷 >> Android >> Android基础札记(七)-页面跳转和数据传递
  详细解决方案

Android基础札记(七)-页面跳转和数据传递

热度:16   发布时间:2016-04-28 02:05:51.0
Android基础笔记(七)-页面跳转和数据传递

  • Activity简介
  • Activity的简单使用
  • Activity之间的跳转
  • 意图传递数据
  • 创建Activity获取返回数据
  • 如何调用系统发送短信的页面
  • 如何发送短信

这里写图片描述

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:[email protected]: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);//启动第二个ActivitystartActivity(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();//设置Actionintent.setAction("com.bzh.SecondActivity");//对于android.intent.category.DEFAULT类型的信息为Android系统默认的信息,省略也可以intent.addCategory("android.intent.category.DEFAULT");//启动ActivitystartActivity(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();// 设置Actionintent.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对象中获取IntentIntent 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

这里写图片描述

  相关解决方案