Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "第5章 Activity与Intent QQ号: QQ群: (Android编程入门) 网络资源:"— Presentation transcript:

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

2 知识导图

3 知识导图

4 实例

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

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

7 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)都必须进行注册。

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

9 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的请求码。这个请求码的值由开发者根据业务自行设置,用于标识请求来源。

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

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

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

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

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

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

16 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。 【】中间的部分可执行一到多次,即前台生命周期循环。

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

18 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"); }

19 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"); }}

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

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

22 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"); }

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

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

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

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

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

28 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方法。此时单击返回按钮,控制台打印信息如下:

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

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

31 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里的数据。

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

33 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中取出各种类型的数据。

34 用户注册案例

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

36 用户注册程序结构分析

37 5.1.5 用户注册案例 下面我们来详细介绍这个程序的开发过程,首先是注册界面的设计,代码如下:
程序清单:RegisterTest\res\layout\activity_main.xml <LinearLayout xmlns:android=" xmlns: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:textColor="#ff0000" android:textSize="24sp" /> <TableLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > →设置文本框属性为水平居中

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

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

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

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

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

43 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:layout_width="wrap_content" android:textSize="20sp" /> <EditText android:layout_height="wrap_content" /> </LinearLayout>

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

45 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();} →验证用户输入信息的结果 →如果结果不为空,则用对话框提示 →设置对话框标题 →设置对话框内容信息 →为对话框添加按钮及 事件处理 →将密码框设置为空 →创建对话框并显示

46 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

47 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; →对用户名进行验证 →对密码进行验证 →对确认密码进行验证

48 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); } });

49 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); }

50 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;

51 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;

52 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];

53 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;

54 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; }};

55 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; }});}}

56 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")); }

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

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

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

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

61 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();//获取组件的类名

62 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类,通过这些常量我们 能调用系统为我们提供的功能。

63 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 创建文件操作选择器

64 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常量的组件。

65 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随系统启动而运行

66 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: 上面所示的两个字符串的冒号前面大致指定了数据的类型,冒号后面的是数据部分。因此一个合法的URI对象既可决定操作哪种数据类型的数据,又可指定具体的数据值。

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

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

69 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。

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

71 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进行匹配,例如“ 4、如果Intent指定了一个或多个Category,这些类别必须全部出现在组件的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

72 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过滤器将被选择。

73 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"。)

74 5.2.3 Activity间数据传递

75 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); } }); }}

76 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); } });}}

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

78


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

Similar presentations


Ads by Google