Android开发四大组件.pptx

上传人:yyf 文档编号:3675696 上传时间:2019-09-20 格式:PPTX 页数:58 大小:2.87MB
返回 下载 相关 举报
Android开发四大组件.pptx_第1页
第1页 / 共58页
Android开发四大组件.pptx_第2页
第2页 / 共58页
Android开发四大组件.pptx_第3页
第3页 / 共58页
Android开发四大组件.pptx_第4页
第4页 / 共58页
Android开发四大组件.pptx_第5页
第5页 / 共58页
点击查看更多>>
资源描述

《Android开发四大组件.pptx》由会员分享,可在线阅读,更多相关《Android开发四大组件.pptx(58页珍藏版)》请在三一文库上搜索。

1、Android开发 四大组件 Android应用程序构成 2 ActivityService Broadcast ReceiverContent Provider Intent Activity 我是activity 因为我是你展现给别 人的最 直接的外观,所以我当然是 美女啦 Activity A visual user interface 通过view管理UI 每一个有用户界面的应用至少包含一个activity 一个应用可以有多个activity,其中一个作为main activity用于启动显示 Activity通过startActivity或startActivityForResult

2、启 动另外的activity 4 ActivityView 通过View管理UI View绘制UI与处理UI event View可通过xml描述定义,也可在代码中生成。 setContentView(R.layout.main) Android建议将UI设计和逻辑分离 android UI设计类似swing,通过布局(layout)组织 UI组件 5 Activity生命周期 Activity通过onCreate被 创建 当一个activity失去焦点 ,该activity将进入pause 状态,系统在内存不足 时会将其终止 当一个activity被另一个 activity覆盖,该activ

3、ity 将进入stop状态,系统 在需要内存的时候会将 其终止 6 Activity生命周期.cont Activity有三个状态: 当它在屏幕前台时(位于当前任务堆栈的顶部),它是激活或运行状 态。它就是响应用户操作的Activity。 当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时(如 右图),它处于暂停状态。在它之上的Activity没有完全覆盖屏幕,或者是 透明的,被暂停的Activity仍然对用户可见,并且是存活状态(它保留着所 有的状态和成员信息并保持和窗口管理器的连接)。如果系统处于内存不 足时会杀死这个Activity。 当它完全被另一个Activity覆

4、盖时则处于停止状态。它仍然保留所有的状态 和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如果其它 地方需要内存,则系统经常会杀死这个Activity。 当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这 种变化: void onCreate(Bundle savedInstanceState) void onStart() void onRestart() void onResume() void onPause() void onStop() void onDestroy() Activity生命周期.cont 这七个方法定义了Activity的完整生命周期

5、。实现这些方法可以帮助我们监视其中的三个嵌套生命 周期循环: Activity的完整生命周期自第一次调用onCreate()开始,直至调用onDestroy()为止。Activity在 onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如 ,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。 Activity的可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以 在屏幕上看到Activity,尽管它也许并不是位于前台或者

6、也不与用户进行交互。在这两个方法之间 ,我们可以保留用来向用户显示这个Activity所需的资源。例如,当用户不再看见我们显示的内容 时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中 来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。 Activity的前台生命周期自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity 位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换例如当设 备转入休眠状态或者有新的A

7、ctivity启动时,将调用onPause() 方法。当Activity获得结果或者接收 到新的Intent时会调用onResume() 方法。关于前台生命周期循环的例子请见PPT下方备注栏。 Activity的onSaveInstanceState()和 onRestoreInstanceState()方法 Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不 同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如 :内存不足、用户直接按Home键)由

8、系统销毁一个Activity时,onSaveInstanceState() 会被调 用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不 会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常 onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保 存。 另外,当屏幕的方向发生了改变, Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁 前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activ

9、ity的 onSaveInstanceState() 和 onRestoreInstanceState()方法,如下: public class PreferencesActivity extends Activity private String name; protected void onRestoreInstanceState(Bundle savedInstanceState) name = savedInstanceState.getString(“name“); /被重新创建后恢复缓存的数据 super.onRestoreInstanceState(savedInstanceSt

10、ate); protected void onSaveInstanceState(Bundle outState) outState.putString(“name“, “liming“);/被摧毁前缓存一些数据 super.onSaveInstanceState(outState); 应用的响应性(Responsive) 在Android中,应用的响应性被活动管理器(Activity Manager) 和窗口管理器(Window Manager)这两个系统服务所监视。 当用户触发了输入事件(如键盘输入,点击按钮等), 如果应用5秒内没有响应用户的输入事件,那么,Android会认 为该应用无

11、响应,便弹出ANR(Application No Response) 对话框。如右图。 在正常情况下,Android程序会在一条单线程里运行。如果Activity要处理一件比较耗时的工作,应 该交给子线程完成,否侧会因为主线程被阻塞,后面的用户输入事件因没能在5秒内响应,导致应 用出现ANR对话框。 为应用添加新的Activity 第一步:新建一个继承Activity的类,如:NewActivity public class NewActivity extends Activity Override protected void onCreate(Bundle savedInstanceSta

12、te) super.onCreate(savedInstanceState); /这里可以使用setContentView(R.layout.xxx)显示某个视图 第二步:需要在功能清单AndroidManifest.xml文件中添加进上面Activity配置代码(红色部分): . . android:name属性值的前面加了一个点表示NewActivity是当前包cn.csst.action下的类,如果类在应 用的当前包下,可以省略点符号,如果类在应用的子包下必须加点,如:NewActivity类在 cn.csst.action.user包下可以这样写: 打开新的Activity ,不传递参

13、数 在一个Activity中可以使用系统提供的startActivity(Intent intent)方法打开新的Activity,在打开新的 Activity前,你可以决定是否为新的Activity传递参数: 第一种:打开新的Activity,不传递参数 public class MainActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) . Button button =(Button) this.findViewById(R.id.button); button.set

14、OnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activity public void onClick(View v) /新建一个显式意图,第一个参数为当前Activity类对象,第二个参数为你要打开的Activity类 startActivity(new Intent(MainActivity.this, NewActivity.class); ); 打开新的Activity,并传递若干个参数给它 第二种:打开新的Activity,并传递若干个参数给它: public class MainActivity extends Act

15、ivity Override protected void onCreate(Bundle savedInstanceState) . button.setOnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activity public void onClick(View v) Intent intent = new Intent(MainActivity.this, NewActivity.class) Bundle bundle = new Bundle();/该类用作携带数据 bundle.putString(“name“, “

16、中软国际“); bundle.putInt(“age“, 4); intent.putExtras(bundle);/附带上额外的数据 startActivity(intent); ); 在新的Activity中接收前面Activity传递过来的参数: public class NewActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) Bundle bundle = this.getIntent().getExtras(); String name = bundle.getS

17、tring(“name“); int age = bundle.getInt(“age“); Bundle类的作用 Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供 了各种常用类型的putXxx()/getXxx()方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于 往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用 了HashMap类型的变量来存放putXxx()方法放入的值: public final cla

18、ss Bundle implements Parcelable, Cloneable Map mMap; public Bundle() mMap = new HashMap(); public void putString(String key, String value) mMap.put(key, value); public String getString(String key) Object o = mMap.get(key); return (String) o; /类型转换失败后会返回null,这里省略了类型转换失败后的处理代码 在调用Bundle对象的getXxx()方法时,

19、方法内部会从该变量中获取数据,然后对数据进行类型转换 ,转换成什么类型由方法的Xxx决定,getXxx()方法会把转换后的值返回。 为Intent附加数据的两种写法 第一种写法,用于批量添加数据到Intent: Intent intent = new Intent(); Bundle bundle = new Bundle();/该类用作携带数据 bundle.putString(“name“, “中软国际“); intent.putExtras(bundle);/为意图追加额外的数据,意图原来已经具有的数据不会丢失,但key同名的数据会被替换 第二种写法:这种写法的作用等价于上面的写法,只不

20、过这种写法是把数据一个个地添加进Intent,这种写 法使用起来比较方便,而且只需要编写少量的代码。 Intent intent = new Intent(); intent.putExtra(“name“, “中软国际“); Intent提供了各种常用类型重载后的putExtra()方法,如: putExtra(String name, String value)、 putExtra(String name, long value),在putExtra()方法内部会判断当前Intent对象内部是否已经存在一个Bundle对象,如果不存 在就会新建Bundle对象,以后调用putExtra()

21、方法传入的值都会存放于该Bundle对象,下面是Intent的 putExtra(String name, String value)方法代码片断: public class Intent implements Parcelable private Bundle mExtras; public Intent putExtra(String name, String value) if (mExtras = null) mExtras = new Bundle(); mExtras.putString(name, value); return this; 得到新打开Activity 关闭后返回的

22、数据 如果你想在Activity中得到新打开Activity 关闭后返回的数据,你需要使用系统提供的 startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的 Activity 传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法: public class MainActivity extends Activity Override

23、protected void onCreate(Bundle savedInstanceState) . Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activity public void onClick(View v) /第二个参数为请求码,可以根据业务需求自己编号 startActivityForResult (new Intent(MainActivity.this, NewActivity

24、.class), 1); ); /第一个参数为请求码,即调用startActivityForResult()传递过去的值 /第二个参数为结果码,结果码用于标识返回数据来自哪个新Activity Override protected void onActivityResult(int requestCode, int resultCode, Intent data) String result = data.getExtras().getString(“result”);/得到新Activity 关闭后返回的数据 当新Activity关闭后,新Activity返回的数据通过Intent进行传递,

25、android平台会调用前面Activity 的 onActivityResult()方法,把存放了返回数据的Intent作为第三个输入参数传入,在onActivityResult()方法中使 用第三个输入参数可以取出新Activity返回的数据。 得到新打开Activity 关闭后返回的数据 使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新Activity关闭前需要向前面的 Activity返回数据需要使用系统提供的setResult(int resultCode, Intent data)方法实

26、现: public class NewActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) button.setOnClickListener(new View.OnClickListener() public void onClick(View v) Intent intent = new Intent();/数据是使用Intent返回 intent.putExtra(“result”, “中软国际的学生很可爱”);/把返回数据存入Intent NewActivity.thi

27、s.setResult(RESULT_OK, intent);/设置返回数据 NewActivity.this.finish();/关闭Activity ); setResult()方法的第一个参数值可以根据业务需要自己定义,上面代码中使用到的RESULT_OK是系统Activity 类定义的一个常量,值为-1,代码片断如下: public class android.app.Activity extends public static final int RESULT_CANCELED = 0; public static final int RESULT_OK = -1; public s

28、tatic final int RESULT_FIRST_USER = 1; 请求码的作用 使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个 请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这 两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的 onActivityRes

29、ult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮 打开的,并且要做出相应的业务处理,这时可以这样做: Override public void onCreate(Bundle savedInstanceState) button1.setOnClickListener(new View.OnClickListener() public void onClick(View v) startActivityForResult (new Intent(MainA

30、ctivity.this, NewActivity.class), 1); ); button2.setOnClickListener(new View.OnClickListener() public void onClick(View v) startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2); ); Override protected void onActivityResult(int requestCode, int resultCode, Intent data) switch(re

31、questCode) case 1: /来自按钮1的请求,作相应业务处理 case 2: /来自按钮2的请求,作相应业务处理 结果码的作用 在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系 统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新 Activity,在onActivityResult()方法中可以这样做(ResultActiv

32、ity和NewActivity为要打开的新Activity): public class ResultActivity extends Activity . ResultActivity.this.setResult(1, intent); ResultActivity.this.finish(); public class NewActivity extends Activity NewActivity.this.setResult(2, intent); NewActivity.this.finish(); public class MainActivity extends Activit

33、y / 在该Activity会打开ResultActivity和NewActivity Override protected void onActivityResult(int requestCode, int resultCode, Intent data) switch(resultCode) case 1: / ResultActivity的返回数据 case 2: / NewActivity的返回数据 Intent 我是intent 我是运输大队长,只有 我,你的数据才能传输 Intent(意图) Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent

34、 (意图) ,Intent提供了一种通用 的消息系统,它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件。使用Intent可以 激活Android应用的三个核心组件:活动、服务和广播接收器。 Intent可以划分成显式意图和隐式意图。 显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意 图明确指定了Intent应该传递给哪个组件。 隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类 别(category)、数

35、据(URI和数据类型)找到最合适的组件来处理这个意图。查找规则请见ppt下方备注。 Intent(1) 类似于消息、事件通知 Intent构成:action、category、data Activity、Service、broadcast receiver之间的桥梁 22 Intent activityservice Broadcast receiver Intent(2) 两类intent: 显式:指定具体的目标组件处理 startActivity(new Intent(ActivityLifecycle.this, AnotherActivity.class); 隐式:由系统接受并决定如何

36、处理 startActivity(new Intent(Intent.ACTION_DIAL); 在AndroidManifest.xml中定义activity、service、broadcast receiver接受的intent 23 Intent(3) Intent filter: action、category、data 24 framework Component name Action Data Category intent component activity service Broadcast receiver 实例 25 action - DIAL data - tel:0

37、2038639592 action - VIEW data - http:/ Service 我是service 我是劳模,只有我,你才 能高枕无忧的随心所欲 Service 没有UI,启动之后一直运行于后台 例子:音乐播放器 与应用程序的其他模块(例如activity)一同 运行于主线程中 通过startService或bindService创建Service 通过stopService或stopSelf终止Service 一般的,在activity中启动和终止service 27 Service生命周期 onCreate onStart onDestroy 28 Context.stopS

38、ervice() Serivce.stopSelf() Context.startService()Context.bindService() 服务-Service Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容 易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下: 第一步:继承Service类 public class SMSService extends Service 第二步:在AndroidManifest.xml文件中的节点里对服务进行配置: 服务不能自己运行,需要通过调用Context.startServ

39、ice()或Context.bindService()方法启动服务。 这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务, 调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务, 调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特 点。 采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结 束时会调用onDestroy()方法。 建立能与Activity进行相互通信的本地

40、服务 通过startService()和stopService()启动关闭服务。适用于服务和调用者之间没有交互的情况。 如果服务和调用者之间需要方法调用或者传递参数,侧需要使用bindService()和 unbindService()方法启动关闭服务。 采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate() 方法,接着调用onBind()方法,这个时候调用者和服务绑定在一起。 如果客户端要与服务进行通 信,那么,onBind()方法必须返回Ibinder对象。如果调用者退出了,系统就会先调用服务的 onUnbind()方法,接着调

41、用onDestroy()方法。如果调用bindService()方法前服务已经被绑定, 多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方 法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService() 方法,调用该方法也会导致系统调用服务的onUnbind()onDestroy()方法。 服务的生命周期回调方法 服务的生命周期跟采用启动服务的方法有关: 当采用Context.startService()方法启动服务,与之有关的生命周期方法 onCreate() onStart() onDe

42、stroy() onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次 startService()或bindService()方法,服务也只被创建一次。 onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开 始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被 多次调用。 onDestroy()该方法在服务被终止时调用。 当采用Context.bindService()方法启动服务,与之有关的生命周期方法 onCreate() onBind()

43、onUnbind() onDestroy() onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服 务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该 方法被多次调用。 onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与 服务解除绑定时被调用。 如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用 unbindService()方法解除绑定,最后调用bind

44、Service()方法再次绑定到服务,触发的生命周期方 法如下: onCreate()onStart()onBind()onUnbind()重载后的方法需返回trueonRebind() 使用AIDL和远程服务实现进程通信 在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间 传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的。因此 要传递对象, 需要把对象解析成操作系统能够理解的数据格式, 以达到跨界对 象访问的目的。在JavaEE中,采用RMI通过序列化传递对象。在Android中, 则 采用AIDL(Android Interface Defini

45、tion Language:接口描述语言)方式实 现。 AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生 成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所 采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息, 然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之 间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双 向转换,代理类由android编译器生成,对开发人员来说是透明的。 实现进程通信,一般需要下面四个步骤:(请见页面下方备注栏) 假设A应用需要与B应用进行

46、通信,调用B应用中的download(String path)方法,B应用以Service方式向A应用提供服 务。需要下面四个步骤: 1 在B应用中创建*.aidl文件,aidl文件的定义和接口的定义很相类,如:在cn.csst.aidl包下创建IDownloadService.aidl 文件,内容如下: package cn.csst.aidl; interface IDownloadService void download(String path); 当完成aidl文件创建后,eclipse会自动在项目的gen目录中同步生成IDownloadService.java接口文件。接口文件中生

47、成 一个Stub的抽象类,里面包括aidl定义的方法,还包括一些其它辅助方法。值得关注的是asInterface(IBinder iBinder), 它返回接口类型的实例,对于远程服务调用,远程服务返回给客户端的对象为代理对象,客户端在 onServiceConnected(ComponentName name, IBinder service)方法引用该对象时不能直接强转成接口类型的实例,而应 该使用asInterface(IBinder iBinder)进行类型转换。 编写Aidl文件时,需要注意下面几点: 1.接口名和aidl文件名相同。 2.接口和方法前不用加访问权限修饰符public

48、,private,protected等,也不能用final,static。 3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),使用这 些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作为参数或 返回值,自定义类型必须实现Parcelable接口。 4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包 中。 5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入 输出参数。 6.Java原始类型默认的标记为in,不能为其它标记。 2 在B应用中实现aidl文件生成的接口(本例是IDownloadService),但并非直接实现接口,而是通 过继承接口的Stub来实现(Stub抽象类内部实现了aidl接口),并且实现接口方法的代码。内容如下 : public class ServiceBinder extends IDownloadService.Stub Override public void download(String path) throws Re

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/环境 > 装饰装潢


经营许可证编号:宁ICP备18001539号-1