第5章 Activity与Intent QQ号: QQ群: (Android编程入门) 网络资源:

Slides:



Advertisements
Similar presentations
网络应用程序设计 2014 JavaBean. JavaBean 及其属性 JavaBean 就是一种 Java 的组件技术 JavaBean 是 Java 类 JavaBean 通过约定的方法名实现属性功能 简单属性 void setXxx(Type value) Type getXxx() boolean.
Advertisements

7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
面向侧面的程序设计 方林博士 本文下载地址:
第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
實驗五:多媒體播放器選單介面.
Part 2 開發Android應用程式的流程
UI(用户界面)集训班 Illustrator 高级班.
位置與地圖應用 此投影片為講解Android如何取得定位經緯度和使用Google Map地圖.
在PHP和MYSQL中实现完美的中文显示
第三章 Android高级界面控件(4) QQ群: Q Q号: 倚动软件工厂实验室.
Android + Web Service 建國科技大學 資管系 饒瑞佶 2017/3 V1.
厦门大学数据库实验室 报告人:谢荣东 导师:林子雨 2014年8月30日
實驗四:單位轉換程式.
Chapter 13 Android 實戰演練.
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
實驗十三:顯示目前經緯度位置.
Signutil.
Ch06 再談選單元件 物件導向系統實務.
使用Android控制Arduino 史先强
7.3 Intent传值.
Android开发入门 -----Activity的一生 主讲:何广军
第8章 Android内容提供者(ContentProvider)应用
Chapter 6 Advanced UI Design.
Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。
Android Intent 建國科技大學 資管系 饒瑞佶 2011/1.
Chapter 6 進階UI設計.
第4章 Android生命周期.
第9章 使用意圖啟動活動與內建應用程式 9-1 意圖的基礎 9-2 使用意圖啟動活動
第4章 Andorid活动与意图 (Activity与Intent)
CH7 佈局、按鈕與文字編輯元件.
Android + Service 建國科技大學 資管系 饒瑞佶.
實驗十四:顯示與控制地圖.
第5章 Activity与Intent.
走进编程 程序的顺序结构(二).
辅导课程六.
第2讲 移动应用开发基础知识(二) 宋婕
网络常用常用命令 课件制作人:谢希仁.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第6章 建立Android使用介面 6-1 介面元件的基礎 6-2 Android的事件處理 6-3 按鈕元件 6-4 文字元件
生活智慧王 樹德科技大學 資訊工程系 指導教授 : 陳毓璋 教授 小組成員: 劉上緯 翁維廷 洪文財.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
實驗十一:待辦事項程式 (儲存在手機上).
主编:钟元生 赵圣鲁.
Intent.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
Android 开发入门.
SOA – Experiment 2: Query Classification Web Service
第四章 团队音乐会序幕: 团队协作平台的快速创建
Location Based Services - LBS
姚金宇 MIT SCHEME 使用说明 姚金宇
计算机网络与网页制作 Chapter 07:Dreamweaver CS5入门
iSIGHT 基本培训 使用 Excel的栅栏问题
3.16 枚举算法及其程序实现 ——数组的作用.
Chapter 18 使用GRASP的对象设计示例.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
郑 昀 应用开发事业部 神州泰岳 SIP多方会话消息 之实例讲解 郑 昀 应用开发事业部 神州泰岳
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Python 环境搭建 基于Anaconda和VSCode.
WSAAsyncSelect 模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang
Android Speech To Text(STT)
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
用Intent啟動程式中的其他Activity、運用WebView顯示網頁 靜宜大學資管系 楊子青
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
第四章 UNIX文件系统.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
第六讲 酒店客房管理系统(二) 教育部“十二五”职业教育国家规划教材
多个Activity的使用 本讲大纲: 1、使用Bundle在Activity之间交换数据 2、调用另一个Activity并返回结果
Presentation transcript:

第5章 Activity与Intent QQ号:1281147324 QQ群:490420731(Android编程入门) 网络资源: http://www.xs360.cn/book

知识导图

知识导图

实例

5.1 Activity详解 Activity是Android应用中重要组成部分之一,如果把一个Android应用看成是一个网站的话,那么一个Activity就相当于该网站的一个具体网页。Android应用开发的一个重要组成部分就是开发Activity。 Activity是一种应用程序组件,该组件提供了一个屏 幕,用户通过与这个屏幕交互可完成一定的功能,例如打 电话,拍照,发送邮件或者查看地图等。 每一个Activity都提供了一个用于显示它的用户界面 的窗口。这个窗口通常会充满整个屏幕,但有可能比这个 屏幕更小或者是漂浮在其他窗口之上。

5.1.1 Activity概述 应用程序通常由多个彼此之间松耦合的Activity组成。通常,在一个应用程序中,有一个Activity被指定为主Activity。当应用程序第一次启动的时候,该Activity会显示给用户。 每个Activity都可以启动其它的Activity用于执行不同的操作(功能)。当一个新的Activity启动的时候,先前的那个Activity就会停止,但是系统在堆栈中仍保存该Activity。 当一个新的Activity启动时,它将会被压入栈顶,并获得用户焦点。堆栈遵循后进先出的队列原则,因此,当用户使用完当前的Activity并按Back键时,该Activity将从堆栈中取出(并销毁),然后先前的Activity恢复并获取焦点。

5.1.2 创建和配置Activity 创建自己的Activity需要继承Activity基类,在不同的应用场景下,有时也要求继承Activity的子类,例如ListActivity、TabActivity。 创建一个Activity需要实现一个或多个方法,其中最常见的就是实现onCreate(Bundle status)方法,该方法将会在Activity创建时被回调,该方法调用Activity的setContentView(View view)方法来显示要展示的View。 为了管理应用程序界面中的各个组件,可调用Activity的findViewById(int id)方法来获取程序界面中的组件,接下来即可修改该组件的属性和方法以满足我们的需求。 Android应用要求所有应用程序组件(Activity、Service、 ContentProvider、BroadcastReceiver)都必须进行注册。

5.1.2 创建和配置Activity 为<application …/>元素添加<activity…/>子元素即可注册Activity。注册时,主要有以下几个属性: name:指定该Activity的实现类的类名; icon:指定该Activity对应的图标; label:指定该Activity的标签。 配置Activity时通常还可以指定一个或多个<intent-filter…/>元素,该元素用于指定该Activity可响应的条件。 上述配置中,只有name属性是必须的,而其它属性或标签元素都是可选的。

5.1.3启动Activity 一个Android应用通常都会包含多个Activity,但只有一个Activity会作为程序的入口(当该Android应用运行时将会自动启动并执行该Activity)。而应用中的其他Activity,通常都由入口Activity启动,或由入口Activity启动的Activity启动。 启动其它Activity的方法如下: startActivity(Intent intent):启动其他Activity; startActivityForResult(Intent intent,int requestCode):程序将会得到新启动Activity的结果(通过重写onActivityResult(…)方法来获取),requestCode参数代表启动Activity的请求码。这个请求码的值由开发者根据业务自行设置,用于标识请求来源。

5.1.3启动Activity 上面两个方法,都需要传入一个Intent类型的参数,该 参数是对你所需要启动的Activity的描述,既可以是一个 确切的Activity类,也可以是所需要启动的Activity的一 些特征,然后由系统查找符合该特征的Activity。 如果有多个Activity符合该要求时,系统将会以下拉列 表的形式列出所有的Activity,然后由用户选择具体启动 哪一个,这些Activity既可以是本应用程序的,也可以是 其他应用程序的。

5.1.3关闭Activity finish():结束当前Activity; finishActivity(int requestCode):结束以startActivityForResult(Intent intent,int requestCode)方法启动的Activity。 注意:大部分情况下,不建议显式调用这些方法关闭Activity。因为Android系统会为我们管理Activity的生命周期,调用这些方法可能会影响用户的预期体验。因此,只有当你不想用户再回到当前Activity的时候才去关闭它。

Activity的生命周期 整个生命周期 可见生命周期 前台生命周期

5.1.4 Activity的生命周期 Activity的三种状态 Resumed:已恢复状态,此时Activity位于前台,并且获得用户焦点,这种状态通常也叫运行时状态; Paused:暂停状态,Activity失去用户焦点,但该Activity仍是可见的,即该Activity仍存在于内存中,并能维持自身状态和记忆信息,且维持着和窗口管理器之间的联系。但是,当系统内存极度缺乏的时候可能杀死该Activity。 Stopped:停止状态,该Activity完全被其他Activity所覆盖,该Activity仍存在于内存中,能维持自身状态和记忆信息,但它和窗口管理器之间已没有了联系。当系统需要内存时,随时可以杀死该Activity。

5.1.4 Activity的生命周期 整个生命周期 可见生命周期 从onCreate()开始到onDestroy()结束。Activity在onCreate()设置所有的“全局”状态,例如界面的布局文件,在onDestory()释放所有的资源。例如:关闭下载进程。 可见生命周期 从onStart()开始到onStop()结束。可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。onStart()和onStop()方法都可以被多次调用,因为Activity随时可在可见和隐藏之间转换,例如:可以在onStart中注册一个监听器来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。

5.1.4 Activity的生命周期 前台生命周期 从onResume()开始到onPause()结束。在这段时间里,该Activity处于所有Activity的最前面,和用户进行交互。Activity可以经常性地在resumed和paused状态之间切换,例如:当设备准备休眠时,当一个 Activity处理结果被分发时,当一个新的Intent被分发时。所以在这些方法中的代码应该属于非常轻量级的。

5.1.4 Activity的生命周期 案例:模拟Activity生命周期中方法的调用。重写Activity生命周期中的方法,方法调用时,在控制台打印出相应的信息,根据信息查看方法调用顺序。 程序运行后,系统会依次调用:onCreate→onStart→onResume,此时MainActivity就处于运行时状态了;退出时,系统依次调用onPause→onStop→onDestroy方法。 onCreate→onStart→onResume→ onPause →onStop→【onRestart→onStart→onResume→ onPause→onStop→】onDestroy。 【】中间的部分可执行零到多次,即可见生命周期循环。 onCreate→onStart→onResume→onPause→【onResume→onPause→】onStop→onDestroy。 【】中间的部分可执行一到多次,即前台生命周期循环。

5.1.4 Activity的生命周期 下面我们以一个简单的程序来模拟Activity的生命周期,该程序中包含三个Avtivity,即MainActivity,SecondActivity,ThirdActivity,这三个Activity都重写了Activity生命周期中所涉及的方法,方法体中主要就是在控制台打印一条信息,表明该方法被调用了,查看控制台的信息即可知道方法调用的顺序,详细代码如下。

5.1.4 Activity的生命周期 程序清单:ActivityLifeCycleTest\src\iet\jxufe\cn\android\MainActivity.java public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button second,third; second=(Button)findViewById(R.id.second); third=(Button)findViewById(R.id.third); second.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent=new Intent(MainActivity.this,SecondActivity.class); startActivity(intent);}}); third.setOnClickListener(new OnClickListener() { Intent intent=new Intent(MainActivity.this,ThirdActivity.class); System.out.println("MainActivity's onCreate"); }

5.1.4 Activity的生命周期 protected void onStart() { super.onStart(); 程序清单:ActivityLifeCycleTest\src\iet\jxufe\cn\android\MainActivity.java protected void onStart() { super.onStart(); System.out.println("MainActivity's onStart"); } protected void onRestart() { super.onRestart(); System.out.println("MainActivity's onRestart"); } protected void onResume() { super.onResume(); System.out.println("MainActivity's onResume"); } protected void onStop() { super.onStop(); System.out.println("MainActivity's onStop"); } protected void onDestroy() { super.onDestroy(); System.out.println("MainActivity's onDestroy"); } protected void onPause() { super.onPause(); System.out.println("MainActivity's onPause"); }}

5.1.4 Activity的生命周期 运行该程序,然后单击返回键退出该程序,控制台打印信息如图: 程序打开后,系统会依次调用:onCreate→onStart→onResume→ 此时,MainActivity就处于运行时状态了;退出时,系统依次调用 onPause→onStop→onDestroy方法。

5.1.4 Activity的生命周期 下面继续模拟有新的Activity启动的情景,首先在原来的界面中添加两个按钮,单击按钮后启动一个新的Activity,界面布局代码如下: 程序清单:ActivityLifeCycleTest\res\layout\activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/second" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/second"/> android:id="@+id/third" android:text="@string/third"/> </LinearLayout>

5.1.4 Activity的生命周期 然后分别为这两个按钮添加事件处理,关键代码如下: 程序清单:ActivityLifeCycleTest\src\iet\jxufe\cn\android\MainActivity.java private Button second,third; public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); second=(Button)findViewById(R.id.second); third=(Button)findViewById(R.id.third); second.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent=new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); } }); third.setOnClickListener(new OnClickListener() { Intent intent=new Intent(MainActivity.this,ThirdActivity.class); System.out.println("MainActivity's onCreate"); }

5.1.4 Activity的生命周期 要实现此功能,还必须添加SecondActivity,ThirdActivity,这两个Activityd的功能和MainActivity的功能相似,就是在相应的回调方法里打印出该方法名,除此之外,还必须在Manifest.xml文件中配置这两个Activity,配置信息如下: 程序清单:ActivityLifeCycleTest\AndroidManifest.xml <activity android:name=".SecondActivity" android:label="@string/title_activity_second" > </activity> android:name=".ThirdActivity" android:label="@string/title_activity_third" android:theme="@android:style/Theme.Dialog" >

5.1.4 Activity的生命周期 此时程序运行效果如下: 此时程序运行效果如下: 单击Go To SecondActivity后控制台打印信息如下:图5-5

5.1.4 Activity的生命周期 此时单击返回键,又会回到MainActivity,并获取焦点,而SecondActivity会自动销毁,控制台打印信息如下: 在此过程中MainActivity的执行流程为:onCreate→onStart→onResume→ onPause→onStop→(onReStarton→onStart→onResume→ onPause→onStop) →onDestroy.()中间的部分可执行零到多次,即可见生命周期循环。

5.1.4 Activity的生命周期 仍然回到MainActivity的界面,单击Go To ThirdActivity按钮,程序跳转到ThirdActivity,运行效果如下:

5.1.4 Activity的生命周期 单击Go To ThirdActivity后,此时控制台打印信息如下:图5-8

5.1.4 Activity的生命周期 对比图5-5和图5-8控制台打印的信息,发现最大的区别在于MainActivity是否调用onStop方法,这也是Activity可见与不可见时的区别。当跳转到SecondActivity时,SecondActivity会完全覆盖了MainActivity,用户看不见它,此时MainActivity会调用onStop方法,而ThirdActivity是以对话框的形式显示的,此时它漂浮于MainActivity之上,对用户而言,仍然可以看到MainActivity,只是无法获取焦点而已,所以,MainActivity会等待新的Activity启动后,(OnCreate OnStart OnResume),再来判断是否要调用onStop方法。此时单击返回按钮,控制台打印信息如下:

问题与讨论 1、当MainActivity正在运行时,若此时直接按Home键,返回到桌面,MainActivity是否还存在?控制台会打印什么消息? 仍然存在,不会调用onDestroy方法。 2、返回到原来的Activity都是使用返回键,如果我们在新启动的Activity中添加一个按钮,单击按钮后,跳转到原来的Activity,这样做与单击返回键有区别吗? 通过按钮跳转到原Activity只是表面现象,实际上系统重新创建了一个Activity,即此时在Activity堆栈中包含两个Activity对象。而通过返回键操作,则是销毁当前的Activity,从而使上一个Activity获取焦点,重新显示在前台,它是不断地从堆栈中取出Activity。

5.1.5 Activity间数据传递 实际应用中,仅仅有跳转还是不够的,往往还需要进行通信,即数据的传递。在Android中,主要是通过Intent对象来完成这一功能的,Intent对象就是它们之间的信使。 数据传递的方向有两个: 从当前Activity传递到新启动的Activity 从新启动的Activity返回结果到当前Activity

startActivityForResult获取返回结果操作: 在当前Activity中重写onActivityResult(int requestCode ,int resultCode,Intent intent)方法,其中requestCode代表请求码,resultCode代表返回的结果码; 在启动的Activity执行结束前,调用该Activity的setResult(int resultCode,Intent intent)方法,将需要返回的结果写入到Intent中。 startActivityForResult执行过程: 当前Activity调用startActivityForResult(Intent intent,int requestCode)方法启动一个符合Intent要求的Activity; 新启动的Activity执行它相应的方法,并将执行结果通过setResult(int resultCode,Intent intent)方法写入Intent; 当该Activity执行结束后,调用原来Activity的onActivityResult(int requestCode ,int resultCode,Intent intent),判断请求码和结果码是否符合要求,从而获取Intent里的数据。

5.1.5 Activity间数据传递 为什么要请求码和结果码? 因为在一个Activity中可能存在多个控件,每个控件都有可能添加相应的事件处理,调用startActivityForResult()方法,从而就有可能打开多个不同的Activity处理不同的业务。但这些Activity关闭后,都会调用原来Activity的onActivityResult(int requestCode, int resultCode, Intent intent)方法。通过请求码,我们就知道该方法是由哪个控件所触发的,通过结果码,我们就知道返回的数据来自于哪个Activity。

5.1.5 Activity间数据传递 Intent保存数据的方法: Intent提供了多个重载的方法来存放额外的数据,主要格式如下: putExtras(String name, Xxx data):其中Xxx表示数据类型,向Intent中放入Xxx类型的数据,例如int、long、String等; 此外还提供了一个putExtras(Bundle data)方法,该方法可用于存放一个数据包,Bundle类似于Java中的Map对象,存放的是键值对的集合,可把多个相关数据放入同一个Bundle中,Bundle提供了一系列的存入数据的方法,方法格式为putXxx(String key, Xxx data),向Bundle中放入int、long、String等各种类型的数据。为了取出Bundle数据携带包中的数据,Bundle还提供了相应的getXxx(String key)方法,从Bundle中取出各种类型的数据。

用户注册案例

5.1.5用户注册案例 运行界面分析

用户注册程序结构分析

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: 程序清单:RegisterTest\res\layout\activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="@string/title" android:textColor="#ff0000" android:textSize="24sp" /> <TableLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > →设置文本框属性为水平居中

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: 程序清单:RegisterTest\res\layout\activity_main.xml <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/name" android:textSize="20sp" /> <EditText android:id="@+id/name" android:layout_width="150dp" android:layout_height="wrap_content" /> android:text="@string/tishi01" android:textColor="#ff0000" android:textSize="16sp" /> </TableRow> →字体颜色为红色 →字体大小为16sp

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/psd" android:textSize="20sp" /> <EditText android:id="@+id/psd" android:password="true" /> android:text="@string/tishi02" android:textColor="#ff0000" android:textSize="16sp" /> </TableRow> 程序清单:RegisterTest\res\layout\activity_main.xml →字体颜色为红色 →字体大小为16sp

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <TableRow> 程序清单:RegisterTest\res\layout\activity_main.xml <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/psd2" android:textSize="20sp" /> <EditText android:id="@+id/psd2" andeoid:inputType="textPassword" android:password="true" /> </TableRow>

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <TableRow> 程序清单:RegisterTest\res\layout\activity_main.xml <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/gender" android:textSize="20sp" /> <RadioGroup android:orientation="horizontal" >

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <RadioButton 程序清单:RegisterTest\res\layout\activity_main.xml <RadioButton android:id="@+id/male" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/male" android:textSize="20sp" /> android:id="@+id/female" android:text="@string/female" </RadioGroup> </TableRow> </TableLayout>

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <LinearLayout 程序清单:RegisterTest\res\layout\activity_main.xml <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/cityBtn" android:layout_width="wrap_content" android:text="@string/city" android:textSize="20sp" /> <EditText android:id="@+id/city" android:layout_height="wrap_content" /> </LinearLayout>

5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下: <Button 程序清单:RegisterTest\res\layout\activity_main.xml <Button android:id="@+id/registerBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/register" android:textSize="20sp" /> </LinearLayout>

5.1.5 用户注册案例 界面设计好了以后,需要对界面中的两个按钮添加相应的事件处理,首先为注册按钮添加事件处理。 程序清单:RegisterTest\src\iet\jxufe\cn\android\MainActivity.java registerBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { String checkResult=checkInfo(); if(checkResult!=null){ Builder builder =new AlertDialog.Builder(MainActivity.this); builder.setTitle("出错提示"); builder.setMessage(checkResult); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { psd.setText(""); psd2.setText(""); } }); builder.create().show();} →验证用户输入信息的结果 →如果结果不为空,则用对话框提示 →设置对话框标题 →设置对话框内容信息 →为对话框添加按钮及 事件处理 →将密码框设置为空 →创建对话框并显示

5.1.5 用户注册案例 界面设计好了以后,需要对界面中的两个按钮添加相应的事件处理,首先为注册按钮添加事件处理。 else{ 程序清单:RegisterTest\src\iet\jxufe\cn\android\MainActivity.java →注册信息符合要求,将数据放入Intent,进行传递 else{ Intent intent=new Intent(MainActivity.this,ResultActivity.class); intent.putExtra("name", name.getText().toString()); intent.putExtra("psd", psd.getText().toString()); String gender=male.isChecked()?"男":"女"; intent.putExtra("gender", gender); intent.putExtra("city",city.getText().toString()); startActivity(intent); } }); →启动一个新的Activity

5.1.5 用户注册案例 在事件处理中,调用了验证用户信息的方法,该方法的代码如下。 程序清单:RegisterTest\src\iet\jxufe\cn\android\MainActivity.java public String checkInfo() { System.out.println(name); if (name.getText().toString() == null||name.getText().toString().equals("")) { System.out.println("***********"); return "用户名不能为空"; } if (psd.getText().toString().trim().length() < 6 || psd.getText().toString().trim().length() > 15){ return "密码位数应该6~15之间"; if(!psd.getText().toString().equals(psd2.getText().toString())){ return "两次输入的密码不一致"; return null; →对用户名进行验证 →对密码进行验证 →对确认密码进行验证

5.1.5 用户注册案例 接下来为所在地按钮添加事件处理,主要是启动获取城市的Activity,代码如下: 程序清单:RegisterTest/src/iet/jxufe/cn/android/MainActivity.java cityBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { →创建需要对应于目标Activity的Intent Intent intent = new Intent(MainActivity.this , ChooseCityActivity.class); →启动指定Activity并等待返回的结果,其中0是请求码,用于标识该请求 startActivityForResult(intent , 0); } });

5.1.5用户注册案例 要实现获取选择的城市信息,还必须在该Activity中重写onActivityResult(int requestCode,int resultCode,Intent intent)方法,代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\MainActivity.java public void onActivityResult(int requestCode , int resultCode, Intent intent) { →当requestCode、resultCode同时为0,也就是处理特定的结果 if (requestCode == 0&& resultCode == 0){ →取出Intent里的Extras数据 Bundle data = intent.getExtras(); →取出Bundle中的数据 String resultCity = data.getString("city"); →修改city文本框的内容 city.setText(resultCity); }

5.1.5用户注册案例 ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java public class ChooseCityActivity extends ExpandableListActivity{ private String[] provinces = new String[]{"江西", "江苏", "浙江"}; private String[][] cities = new String[][]{ { "南昌", "九江", "赣州", "吉安" }, { "南京", "苏州", "无锡", "扬州" }, { "杭州", "温州" , "台州" , "金华" } }; public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); ExpandableListAdapter adapter = new BaseExpandableListAdapter(){ →获取指定组位置的指定子列表项数据 public Object getChild(int groupPosition, int childPosition){ return cities[groupPosition][childPosition]; } public long getChildId(int groupPosition, int childPosition){ return childPosition;

5.1.5用户注册案例 ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java →获取指定组的列表项数,即各省份的城市数 public int getChildrenCount(int groupPosition){ return cities[groupPosition].length; } private TextView getTextView(){ AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 64); TextView textView = new TextView(ChooseCityActivity.this); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); textView.setPadding(36, 0, 0, 0); textView.setTextSize(20); return textView;

5.1.5用户注册案例 ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: →该方法决定每个子选项的外观 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java →该方法决定每个子选项的外观 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent){ TextView textView = getTextView(); textView.setText(getChild(groupPosition, childPosition).toString()); return textView; } →获取指定组位置处的组数据 public Object getGroup(int groupPosition){ return provinces[groupPosition];

5.1.5用户注册案例 →获取该扩展列表的组数,即省份数 public int getGroupCount(){ ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java →获取该扩展列表的组数,即省份数 public int getGroupCount(){ return provinces.length; } →获取组的ID号,即省份的ID号 public long getGroupId(int groupPosition){ return groupPosition;

5.1.5用户注册案例 ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: →该方法决定每个组选项的外观 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java →该方法决定每个组选项的外观 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { LinearLayout ll = new LinearLayout(ChooseCityActivity.this); ll.setOrientation(LinearLayout.VERTICAL); ImageView logo = new ImageView(ChooseCityActivity.this); ll.addView(logo); TextView textView = getTextView(); textView.setText(getGroup(groupPosition).toString()); ll.addView(textView); return ll; } public boolean isChildSelectable(int groupPosition, int childPosition){ return true; } public boolean hasStableIds(){ return true; }};

5.1.5用户注册案例 ChooseCityActivity主要就是一个扩展下拉列表,详细代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\ChooseCityActivity.java setListAdapter(adapter); →设置该窗口显示列表 getExpandableListView().setOnChildClickListener( new OnChildClickListener(){ public boolean onChildClick(ExpandableListView parent, View source, int groupPosition, int childPosition, long id){ →获取启动该Activity之前的Activity对应的Intent Intent intent = getIntent(); Bundle data = new Bundle(); data.putString("city" ,cities[groupPosition][childPosition]); intent.putExtras(data); →设置该SelectActivity的结果码,并设置结束之后退回的Activity ChooseCityActivity.this.setResult(0 , intent); →结束SelectCityActivity ChooseCityActivity.this.finish(); return false; }});}}

5.1.5用户注册案例 结果显示界面的Activity为ResultActivity,该Activity主要就是获取Intent中的数据,代码如下: 程序清单:RegisterTest\src\iet\jxufe\cn\android\ResultActivity.java public class ResultActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_result); TextView resultName=(TextView)findViewById(R.id.resultName); TextView resultPsd=(TextView)findViewById(R.id.resultPsd); TextView resultGender=(TextView)findViewById(R.id.resultGender); TextView resultCity=(TextView)findViewById(R.id.resultCity); Intent intent=getIntent();→获取传递过来的Intent →从Intent中获取的值 resultName.setText(intent.getStringExtra("name")); resultPsd.setText(intent.getStringExtra("psd")); resultGender.setText(intent.getStringExtra("gender")); resultCity.setText(intent.getStringExtra("city")); }

5.1.5用户注册案例 <activity android:name=".ResultActivity" 注意:要实现这个功能,必须要在AndroidManifest.xml文件中,配置ChooseCityActivity和ResultActivity,配置信息如下: 程序清单:RegisterTest/AndroidManifest.xml <activity android:name=".ResultActivity" android:label="@string/result" > </activity> android:name=".ChooseCityActivity" android:label="@string/select" > →注册ResultActivity →注册ChooseCityActivity

5.2 Intent概述 什么是Intent? 在Android应用中,三种核心组件:Activity、Service、 BroadcastReceiver彼此是独立的,它们之所以可以互相调用、协调 工作,最终形成一个具有一定功能的Android应用,主要是通过 Intent对象协助来完成的。 “Intent”中文翻译为“意图”,是对一次即将运行的操作的 抽象描述,包括操作的动作、动作涉及数据、附加数据等,Android 系统则根据Intent的描述,负责找到对应的组件,并将Intent传递 给调用的组件,完成组件的调用。因此,Intent在这里起着媒体中 介的作用,专门提供组件互相调用的相关信息,实现调用者与被调 用者之间的解耦。

5.2.1Intent详解 例如,我们想通过联系人列表查看某个联系人的详细信息,点击某个联系人后,希望能够弹出此联系人的详细信息。 为了实现这个目的,联系人Activity需要构造一个Intent,这个Intent 用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“具体的某个联系人”,然后调用startActivity (Intent intent),将构造的Intent 传入,系统会根据此Intent中的描述,到AndroidManifest.xml中找到满足此Intent 要求的Activity,最终传入Intent,对应的Activity则会根据此Intent 中的描述,执行相应的操作。 Intent实际上就是一系列信息的集合,既包含对接收该Intent的组件有用的信息,如即将执行的动作和数据,也包括对Android系统有用的信息,如处理该Intent的组件的类型以及如何启动一个目标Activity。

5.2.2 Intent构成 Intent构成 Component name(组件名):指定Intent的目标组件名称,即组件的类名。 通常 Android会根据Intent中包含的其他属性信息进行查找,比如action、data/type、category,最终找到一个与之匹配的目标组件。 但如果component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。 指定了这个属性以后,Intent的其他所有属性都是可选的。Intent的Component name属性需要接受一个ComponentName对象,创建ComponentName对象时需要指定包名和类名,从而可唯一确定一个组件类,这样应用程序即可根据给定的组件类去启动特定的组件。

5.2.2 Intent构成 代码如下: 等价于: 在启动的组件中,通过以下语句获取相关的信息: ComponentName comp=new ComponentName(Context con,Class class); Intent intent=new Intent(); Intent.setComponent(comp); 等价于: Intent intent=new Intent(Context con,Class class); 在启动的组件中,通过以下语句获取相关的信息: ComponentName comp=getIntent().getComponent(); comp.getPackageName();//获取组件的包名 comp.getClassName();//获取组件的类名

5.2.2 Intent构成 action(动作): Action代表该Intent所要完成的一个抽象“动作”,这个动作具 体由哪个组件来完成,Action这个字符串本身并不管。 例如Android提供的标准Acton:Intent.ACTION_VIEW,它只表示 一个抽象的查看操作,但具体查看什么,启动哪个Activity来查看, 它并不知道(这取决于Activity的<intent-filter.../>配置,只要 某个Activity的<intent-filter.../>配置中包含了该ACTION_VIEW, 该Activity就有可能被启动)。 Intent类中定义了一系列的Action常量,具体的可查阅Android SDK→reference中的Android.content.intent类,通过这些常量我们 能调用系统为我们提供的功能。

AndroidManifest.xml配置名称 常用Action Action名称 AndroidManifest.xml配置名称 描述 ACTION_MAIN android.intent.action.MAIN 作为一个程序的入口,不需要接收数据 ACTION_VIEW android.intent.action.VIEW 用于数据的显示 ACTION_DIAL android.intent.action.DIAL 调用电话拨号程序 ACTION_EDIT android.intent.action.EDIT 用于编辑给定的数据 ACTION_PICK android.intent.action.PICK 从特定的一组数据之中进行数据的选择操作 ACTION_RUN android.intent.action.RUN 运行数据 ACTION_SEND android.intent.action.SEND 调用发送短信程序 ACTION_GET_CONTENT android.intent.action.GET_CONTENT 根据指定的Type来选择打开操作内容的Intent ACTION_CHOOSER android.intent.action.CHOOSER 创建文件操作选择器

5.2.2 Intent构成 category(类别): 执行动作的组件的附加信息。例如LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATE- GORY表示当前的Intent是一系列的可选动作中的一个,这些动作可以在同 一块数据上执行。同样的,在Intent类中定义了一些Category常量。 一个Intent对象最多只能包括一个Action属性,程序可调用的 setAction(String str)方法来设置Action属性值;但一个Intent对象可以 包含多个Category属性,程序可调用Intent的addCategory(String str) 方法来为Intent添加Category属性。 当程序创建Intent时,该Intent默认启动Category属性值为 Intent.CATEGORY_DEFAULT常量的组件。

5.2.2 Intent构成 Intent类中部分Category常量表 Category常量 对应字符串 简单描述 CATEGORY_DEFAULT android.intent.category.DEFAULT 默认的Category CATEGORY_BROWSABLE android.intent.category. BROWSABLE 指定该Activity能被浏览器安全调用 CATEGORY_TAB android.intent.category. TAB 指定Activity作为TabActivity的Tab页 CATEGORY_LAUNCHER android.intent.category. LAUNCHER Activity显示在顶级程序列表中 CATEGORY_HOME android.intent.category. HOME 设置该Activity随系统启动而运行

5.2.2 Intent构成 data(数据): content://com.android.contacts/contacts/1 Data属性通常用于向Action属性提供操作的数据。不同的Action通常需要携带不同的数据,例如如果Action是ACTION_CALL,那么数据部分将会是tel:需要拨打的电话号码。 Data属性接受一个URI对象,一个URI对象通常通过如下形式的字符串来表示: content://com.android.contacts/contacts/1 tel:13876523467 上面所示的两个字符串的冒号前面大致指定了数据的类型,冒号后面的是数据部分。因此一个合法的URI对象既可决定操作哪种数据类型的数据,又可指定具体的数据值。

5.2.2 Intent构成 Android中部分数据表 操作类型 Data(Uri)格式 范例 浏览网页 http://网页地址 http://www.baidu.com 拨打电话 tel:电话号码 tel:15970142365 发送短信 smsto:短信接收人号码 smsto: 13621384455 查找SD卡文件 file:///sdcard/文件或目录 file:///sdcard/mypic.jpg 显示地图 geo:坐标,坐标 geo:31.899533,-27.036173

5.2.2 Intent构成 type(数据类型):显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。通常来说当Intent不指定Data属性时Type属性才会起作用,否则Android系统将会根据Data属性来分析数据的类型,因此无须指定Type属性。 extras(附加信息):是其它所有附加信息的集合,以键值对形式保存所有的附加信息。使用extras可以为组件提供扩展信息。比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

5.2.2 Intent构成 <intent-filter.../>元素是AndroidManifest.xml文件中<activity…/>元素的子元素,该子元素用于配置该Activity所能“响应”的Intent。 <intent-filter…/>元素里通常可包含如下子元素: 0-N个<action…/>子元素 0-N个<category…/>子元素 0-1个<data…/>子元素 当<activity…/>元素里的<intent-filter…/>子元素里包含多个<action…/>子元素(相当于指定了多个字符串)时,就表明该Activity能响应Action属性值为其中任意一个字符串的Intent。

5.2.3 Intent解析 Android如何解析Intent? 直接(显式)Intent:指定了component 属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。 间接(隐式)Intent:没有指定component 属性的Intent。这些Intent 需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,确定满足此Intent 的组件。

5.2.3 Intent解析 Android系统中Intent解析的判断方法如下: 1、如果Intent指明了Action,则目标组件的IntentFilter的Action列表中就必须包含有这个Action,否则不能匹配; 2、如果Intent没有提供Type,系统将从Data中得到数据类型。和Action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配; 3、如果Intent中的数据不是content类型的URI,而且Intent也没有明确指定它的Type类型,将根据Intent中数据的Scheme进行匹配,例如“http:”或“tel:”。同上,Intent的Scheme必须出现在目标组件的Scheme列表中; 4、如果Intent指定了一个或多个Category,这些类别必须全部出现在组件的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

5.2.3 Intent解析 Android系统中Intent解析的匹配过程如下: 1、Android系统把所有应用程序包中的Intent过滤器集合在一起,形成一个完整的Intent过滤器列表; 2、在Intent与Intent过滤器进行匹配时,android系统会将列表中所有Intent过滤器的“动作”和“类别”与Intent进行匹配,任何不匹配的Intent过滤器都将被过滤掉,没有指定“动作”的Intent请求可以匹配任何的Intent过滤器。 3、把Intent数据URI的每个子部与Intent过滤器的<data>标签中的属性进行匹配,如果<data>标签指定了协议、主机名、路径名或MIME类型,那么这些属性都要与Intent的URI数据部分进行匹配,任何不匹配的Intent过滤器均被过滤掉; 4、如果Intent过滤器的匹配结果多于一个,则可以根据在<intent-filter>标签中定义的优先级标签来对Intent过滤器进行排序,优先级最高的Intent过滤器将被选择。

5.2.3 Intent解析 注意: 理论上说, 一个intent对象如果没有指定category, 它应该能通过任意的category 测试。有一个例外: android把所有传给startActivity()的隐式intent看做至少有一个category: “android.intent.category.DEFAULT”。 因此, 想要接受隐式intent的activity,必须在intent filter中加入“android.intent.category.DEFAULT”。(“android.intent.action.MAIN” 和“android.intent.category.LAUNCHER”的intent filter例外,它们不需要"android.intent.category.DEFAULT"。)

5.2.3 Activity间数据传递

5.2.3 拨号案例 调用系统拨号功能的关键代码如下: 程序清单:DailTest\src\iet\jxufe\cn\android\MainActivity.java public class MainActivity extends Activity { EditText editText; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.num); Button myBtn = (Button) findViewById(R.id.mybtn); myBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { Uri uri=Uri.parse("tel:"+ editText.getText().toString()); →将字符串转换成Uri对象 Intent intent = new Intent(Intent.ACTION_CALL, uri); →第一个参数表示操作的动作,系统根据这个会调用拨号功能 →第二个参数用于指定操作的数据,即向拨打哪个号码 MainActivity.this.startActivity(intent); } }); }}

5.2.3 短信案例 调用系统发送短信功能的关键代码如下: 程序清单:DailTest\src\iet\jxufe\cn\android\MainActivity.java public class MainActivity extends Activity { private EditText shoujihao,xinxi; private Button bn1; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shoujihao = (EditText)findViewById(R.id.shoujihao); xinxi = (EditText)findViewById(R.id.xinxi); bn1 = (Button)findViewById(R.id.bn1); bn1.setOnClickListener(new OnClickListener(){ public void onClick(View arg0) { String mobile = shoujihao.getText().toString(); String content = xinxi.getText().toString(); Intent intent = new Intent(); intent.setData(Uri.parse("smsto:"+mobile)); intent.putExtra("sms_body", content); startActivity(intent); } });}}

5.2.3 Activity间数据传递 注意: 由于调用了系统的拨号功能,因此需要在AndroidManifest.xml文件中添加拨号的权限。否则无法实现该功能,添加的权限代码如下。 <uses-permission android:name="android.permission.CALL_PHONE"/> 权限代码放在Application元素外面,和Application元素属于同一级别。 练习: 编写一个简单的浏览器应用,要求包含一个文本输入框,用于输入网址,单击浏览即可打开该网页,例如输入“http://www.baidu.com”,即可访问百度首页。(提示:可调用系统的Action:ACTION_VIEW,添加访问网络权限。)