怎么将java程序转化为java底层技术代码被封装的应用程序

115 java 面试题目 翻译98
上亿文档资料,等你来发现
115 java 面试题目 翻译98
面向对象编程(OOP);常见的Java问题;垃圾收集器;面向对象编程(OOP);Java是一个支持并发、基于类和面向对象的计算机;代码开发模块化,更易维护和修改;?代码复用;?增强代码的可靠性和灵活性;?增加代码的可理解性;面向对象编程有很多重要的特性,比如:封装,继承,;封装;封装给对象提供了隐藏内部特性和行为的能力;下面列出了使用封装的一些好处:;通过隐
面向对象编程(OOP)常见的Java问题 垃圾收集器面向对象编程(OOP)Java是一个支持并发、基于类和面向对象的计算机编程语言。下面列出了面向对象软件开发的优点:代码开发模块化,更易维护和修改。? 代码复用。? 增强代码的可靠性和灵活性。? 增加代码的可理解性。 ?面向对象编程有很多重要的特性,比如:封装,继承,多态和抽象。下面的章节我们会逐个分析这些特性。封装封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。在Java当中,有3种修饰符:public,private和protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访问权限。下面列出了使用封装的一些好处:通过隐藏对象的属性来保护对象内部的状态。? 提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。? 禁止对象之间的不良交互提高模块化。 ?参考这个文档获取更多关于封装的细节和示例。多态多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力。一个多态类型上的操作可以应用到其他类型的值上面。继承继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用行,也可以在不修改类的情况下给现存的类添加新特性。抽象抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细节来创建类。Java支持创建只暴漏接口而不包含方法实现的抽象的类。这种抽象技术的主要目的是把类的行为和实现细节分离开。抽象和封装的不同点抽象和封装是互补的概念。一方面,抽象关注对象的行为。另一方面,封装关注对象行为的细节。一般是通过隐藏对象内部状态信息做到封装,因此,封装可以看成是用来提供抽象的一种策略。 常见的Java问题1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。2.JDK和JRE的区别是什么?Java运行时环境(JRE)是将要执行Java程序的Java虚拟机。它同时也包含了执行applet需要的浏览器插件。Java开发工具包 (JDK)是完整的Java软件开发包,包含了JRE,编译器和其他的工具(比如:JavaDoc,Java调试器),可以让开发者开发、编译、执行 Java应用程序。3.”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。 Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。4.是否可以在static环境中访问非static变量?static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。5.Java支持的数据类型有哪些?什么是自动拆装箱?Java语言支持的8中基本数据类型是:???????? byte short int long float double boolean char自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之就是自动拆箱。6.Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。7.Java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。Java不支持像C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的复制构造函数。8.Java支持多继承么?不支持,Java不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。9.接口和抽象类的区别是什么?Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:??????? 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。 类可以实现很多个接口,但是只能继承一个抽象类 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。 抽象类可以在不提供接口方法实现的情况下实现接口。 Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。 Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。 接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。也可以参考JDK8中抽象类和接口的区别10.什么是值传递和引用传递?对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。Java线程11.进程和线程的区别是什么?进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。12.创建线程有几种不同的方式?你喜欢哪一种?为什么?有三种方式可以用来创建线程:继承Thread类? 实现Runnable接口? 应用程序可以使用Executor框架来创建线程池 ?实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。13.概括的解释下线程的几种可用状态。线程在执行过程中,可以处于下面几种状态:??????? 就绪(Runnable):线程准备运行,不一定立马就能开始执行。 运行中(Running):进程正在执行线程的代码。 等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。 睡眠中(Sleeping):线程被强制睡眠。 I/O阻塞(Blocked on I/O):等待I/O操作完成。 同步阻塞(Blocked on Synchronization):等待获取锁。 死亡(Dead):线程完成了执行。14.同步方法和同步代码块的区别是什么?在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁)。15.在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。16.什么是死锁(deadlock)?两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。17.如何确保N个线程可以访问N个资源同时又不导致死锁?使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。 Java集合类18.Java集合类框架的基本接口有哪些?Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。Java集合类里面最基本的接口有:Collection:代表一组对象,每一个对象都是它的子元素。? Set:不包含重复元素的Collection。? List:有顺序的collection,并且可以包含重复元素。 ?? Map:可以把键(key)映射到值(value)的对象,键不能重复。19.为什么集合类没有实现Cloneable和Serializable接口?集合类接口指定了一组叫做元素的对象。集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。有的集合类允许重复的键,有些不允许。20.什么是迭代器(Iterator)?Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的 迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。21.Iterator和ListIterator的区别是什么?下面列出了他们的区别:Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。? Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。? ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。 ?22.快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响。java.util包下面的所有的集合类都是快速失败的,而 java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出 ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。23.Java中的HashMap的工作原理是什么?Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode() 和equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合 中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。24.hashCode()和equals()方法的重要性体现在什么地方?Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没 有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法 的实现对HashMap的精确性和正确性是至关重要的。25.HashMap和Hashtable有什么区别?HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点: ? HashMap允许键和值是null,而Hashtable不允许键或者值是null。? Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。 ?包含各类专业文献、各类资格考试、幼儿教育、小学教育、专业论文、高等教育、应用写作文书、行业资料、生活休闲娱乐、文学作品欣赏、115 java 面试题目 翻译98等内容。 
 115 个 Java 面试题和答案――终极列表(上)
| 分类: 基础技术 ... JAVA, 面试 分享到:193 本文由 ImportNew - miracle1919 翻译自 javacodegeeks...   115个Java面试题及回答_求职/面试_求职/职场_应用文书。115 个 Java 面试题及回答原文地址 面向对象编程(OOP) Java 是支持并发,基于类的以及面向对象的一种...   115个Java面试题及回答_求职/面试_求职/职场_应用文书。115个Java面试题及...115. 什么是隐式对象?他们是什么? JSP 隐式对象是指 JSP 容器在每页中提供...   115道java面试题_求职/面试_求职/职场_应用文书。115道java面试题,经典,对找工作非常有帮助本文我们将要讨论 Java 面试中的各种不同类型的面试题,它们可以让...   115个Java面试题和答案――终极列表_求职/面试_求职/职场_应用文书。目录面向...115.隐含对象是什么意思?有哪些隐含对象? JSP 隐含对象是页面中的一些 Java ...   115个Java面试题和答案_面试_求职/职场_实用文档。115 个 Java 面试题和答案――终极列表(上)分享到:184 本文由 ImportNew - miracle1919 翻译自 javacodegeeks...   115个Java面试题和答案――终极列表(上)_求职/面试_求职/职场_应用文书。115 个 Java 面试题和答案――终极列表(上)本文由 ImportNew - miracle1919 翻译自 ...   java常见单词翻译 6页 免费 JAVA面试题集(2) 4页 免费 java面试题2 4页 免费 当代国外翻译理论 21页 2下载券喜欢此文档的还喜欢...   2012 各大公司Java面试经典题目总结(珍藏版)_...115 5、XML 文档定义有几种形式?它们之间有何本质...tomcat.apache.org/ 首页的这一段话用中文翻译一...当前位置: >
> android 应用程序法令(转)
android 应用程序法令(转)
miniwings & at
android 应用程序法则(转)
进程和生命周期Android应用程序是用Java编程语言编写的。编译后的Java代码 —包括应用程序需要的任何数据和资源— 被aapt工具封装到Android包中,使用.apk后缀的包文件。该文件是发布和安装到移动设备的媒介;它是用户下载到他们的设备上的文件。在一个.apk文件中的所有代码就是一个应用程序。 大多数情况下,每个Android 应用程序运行于自己的空间中: 默认情况下,每个应用程序运行于自己的 Linux 进程中。 Android 会在应用程序的任意代码被执行时启动进程,在不需要该进程并且其它应用程序需要系统资源时停止该进程。每个进程有它自己的Java 虚拟机(VM),所以应用程序代码运行于与其他所有应用程序隔绝的环境中。默认每个应用程序被赋予一个不重复的 Linux用户ID。权限被设为只有该用户可以看到应用程序的文件,就是只对应用程序自己可见。—虽然有办法是其他程序可见。在需要看到彼此的文件时,让两个用户共享一个相同的用户ID,是可能的。为了保护系统资源,具有相同ID的应用程序可以安排在同一个Linux进程中运行,共享同一个虚拟机。 应用程序组件Android的一个核心特性是,一个应用程序可以使用其它应用程序的元素(那些应用程序可以提供的)。例如,你的应用程序需要显示一个图片的滚动列表,另外一个应用程序开发了适合的滚动组件并且允许其它应用程序使用它,那么你可以调用该组件来完成显示工作,不用自己再开发了。你的应用程序不需要合并代码或者链接到该程序。只是简单的在需要的时候启动其他应用程序的那部分即可。 为了使该特性可用,系统必须能够在应用程序的任何一部分需要执行时启动应用程序进程,并实例化其Java对象。也就是说,不象其它系统上的应用程序,Android应用程序没有单一的入口点(比如说,没有main()函数)。它只实例化和运行必要的组件。有四种类型的组件: 活动活动 为用户提供有焦点的可视用户界面。例如,活动可以提供一个可供用户选择的菜单项目一览,或者带有图像的标题。一个文本消息应用程序,可以有一个活动用于显示发送消息的联系人列表,另一个活动用于书写要发送的消息,其它的活动用于显示旧的消息或者修改设置。虽然由它们构成了用户界面,但是活动是彼此独立的。每个都作为实现了基类 Activity的子类。 应用程序可以由一个活动构成,或者象刚刚提到的文本消息应用程序一样,可以包含多个活动。活动什么样、有多少,依赖于不同的应用程序及其设计。典型的应用程序会包含一个标记为应用程序启动时,首先呈现给用户的活动。从一个活动迁移到另一个,可以通过当前活动启动另一个活动来完成。 每个活动会被赋予一个缺省的绘制窗口。典型的窗口是覆盖整个屏幕的,但它可以比屏幕小并且浮在其它窗口上方。一个活动也可以使用附加的窗口 — 例如,在活动的中,请求用户响应的弹出对话框,或者当用户在屏幕上选择了一个特别的项目时,向用户呈现一个含有重要信息的窗口。 窗口的可视内容是由层次结构的视图提供的— 从基类 View派生的对象。每个视图控制着窗口中的一部分矩形区域。父视图容纳并组织其子视图的布局。叶视图(那些最底层的视图)在矩形中绘制内容,它们在该空间直接控制并响应用户的动作。就是说,视图是活动与用户交互的地方。例如,视图可以显示一幅图像,当用户碰了图像时执行一个动作。Android有一些现成的视图可以使用 —包括按钮、文本框、滚动条、菜单项、复选框等等。 在活动的窗口中是通过函数 Activity.setContentView() 设置视图的。内容视图是位于层次的根部的视图对象。(关于视图及其层次的详细信息,参见用户界面) 服务服务没有可视用户界面,而是在后台无限期的运行。例如,服务可以在用户做其它事情时播放背景音乐,或者从网络上取得数据,或者做计算工作,然后返回活动需要的结果。每个服务都扩展自Service基类。 最好的例子是媒体播放器根据播放列表来播放音乐。播放器会有一个或多个活动,允许用户选择和播放音乐。音乐播放本身当然不能由活动来完成,因为用户会希望在他离开播放器去做其它事情时,仍然可以让音乐继续播放。为了保持音乐播放,活动可以启动一个服务在后台运行。系统将保持音乐播放服务的执行,即使启动它的活动已经不在屏幕上了。 连接(绑定)到一个正在运行的服务(如果它没有运行的话,就启动它)是可能的。连接上之后,你就可以通过服务提供的接口与它通信了。对于音乐服务,接口可能允许用户暂停、恢复、停止和重新开始播放。 象活动一样,其它组件、服务也在应用程序进程的主线程中运行。为了不阻断其它组件或用户界面,耗时的任务(比如播放音乐)经常会切换到其它线程。参见后面的进程和线程。 广播接收器广播接收器 是一个不做什么实质性工作的组件,只是接收广播通知并对其作出反应。系统代码中有很多广播源 — 例如,通知时区变更、电池电量低、选择了一个图片或者用户更改了语言选项。应用程序也可以初始化广播, —例如,让其它应用程序知道,数据已经下载到设备并可以使用了。 应用程序可以有任意数量的广播接收器,分别对有用的通知作出反应。所有的广播接收器都扩展自 BroadcastReceiver基类。 广播接收器不显示用户界面。它们可以启动活动来响应受到的信息,或者使用 NotificationManager来通知用户。通知可以通过多种方式引起用户的注意 — 背光闪烁、振动、播放音乐等等。典型地是在状态栏显示一个特定图标,用户可以打开它来取得信息。 内容提供者内容提供者生成一个提供给其它应用程序,可访问的数据集合。数据可以存储在文件系统中、SQLite 数据库中或者其它可以使用的任何形式。内容提供者通过扩展 ContentProvider基类,实现一套标准的方法,以使其它应用程序可以取得和存储它控制的类型的数据。不过应用程序并不调用这些方法。它们使用 ContentResolver对象来调用。 ContentResolver可以与任何内容提供者交互,它与提供者一起来管理复杂的进程间的通信。 关于内容提供者的更多信息,参见文档 内容提供者 当有请求需要由应用程序的部分组件处理时, Android负责确保组件所属应用程序进程的运行,需要时会启动该进程;并保证组件的实例可用,在需要时创建实例。 激活组件:意图内容提供者在被ContentResolver请求时激活。另外三个组件— 活动、服务和广播接收者— 通过叫做意图的异步的消息激活。意图是一个 Intent 对象,它保持着信息的内容。对于活动和服务,它指明请求的动作,指定动作需要的数据的URI和其它内容。例如,它可以对活动发出一个请求,要求显示一幅图像或者让用户编辑一些文本。对于广播接收者,意图对象指明广播的动作。例如,它可以对感兴趣的接收者发出快门被按下的消息。 还有其它方法来激活各种组件: 活动可以通过传递一个意图对象到 Context.startActivity() 或 Activity.startActivityForResult()来启动(或执行新的动作)。做出响应的活动可以通过调用 getIntent()方法取得使其运行的意图。 Android调用活动的 onNewIntent()方法传递任何之后的意图。 一个活动经常启动另一个。如果它想得到它启动的活动的结果,它可以调用 startActivityForResult()来代替 startActivity()。例如,你启动了一个活动,让用户选择一幅照片,就需要它返回的选中的照片。结果通过调用活动时传入 onActivityResult()方法的意图返回。 通过传递意图对象到 Context.startService()来启动服务(或者给正在运行的服务新的指令)。 Android调用服务的 onStart()方法,并传给它意图对象。同样的,可以将意图传递给 Context.bindService()来建立调用组件和目标服务之间的连接。服务会在 onBind()被调用时收到意图对象。(如果服务没有运行 bindService()会启动它。) 例如,活动可以与刚才提到的音乐播放服务建立连接,以便是用户(通过用户界面)可以控制播放。活动将调用 bindService()来设置连接,之后调用定义的方法来控制播放。 后面的章节,远程过程调用 有关于绑定服务的更详细的介绍。 应用程序可以初始化一个广播,通过传递一个意图对象到象 Context.sendBroadcast()、 Context.sendOrderedBroadcast()、和 Context.sendStickyBroadcast()的方法,并传入需要的变量。 Android传送意图到所有对它赶兴趣的广播接收者,通过调用它们的 onReceive()方法。关于意图的更多信息,参见另外的文章 意图和意图过滤器。 停止组件内容提供者只有在响应ContentResolver的请求时激活。广播接收者只有在它对广播的消息作出响应时激活。因此它们不需要显式的停止它们的组件。 与之对应的,活动提供用户界面。它们在与用户的长期会话中,保持运行,无论空闲时还是会话中。与活动类似,服务也可以长时间保持运行。因此,Android有按顺序停止活动和服务的方法: 活动可以通过调用它的 finish()方法来停止。一个活动可以停止另一个活动(由它通过, startActivityForResult()启动的),通过调用finishActivity()方法。服务可以通过调用它的 stopSelf()方法或Context.stopService() 方法来停止它。组件也可能被系统停止,当它们不再使用时、或者Android为了活跃组件的运行,必须回收内存时。后面的组件生命周期将讨论它的可能性及各种情况的详细介绍。 清单文件在Android可以启动应用程序组件之前,它必须知道该组件的存在。因此,应用程序在清单文件中声明它们的组件,该文件包含在Android包中, .apk 文件还包含应用程序代码、文件和资源。 清单文件是结构化的XML文件,对于所有应用程序,文件名均为AndroidManifest.xml。它除了声明应用程序组件外,还做一些额外工作,比如指出应用程序需要链接的库(除了Android默认的库)、标明应用程序被授予的权限。 但是,清单文件的主要任务是报告Android应用程序的组成部分。例如,活动可以如下那样声明: &&&&&&&&&&&&&&&&& android:icon="@drawable/small_pic.png"&&&&&&&&&&&&& android:label="@string/freneticLabel"&&&&&&&&&&&&& . . .& $>$&&&&&& . . .元素的 name属性命名实现了活动的 Activity子类。 icon和 label属性,指出代表活动、呈现给用户的包含图标和标签的资源文件。 其它组件也许以类似的方式声明— 元素用于服务, 元素用于广播接收者, 元素用于内容提供者。活动、服务和内容提供者如果不在清单文件中声明的话,对系统是不可见的,因此永远不会运行。广播接收者可以在清单文件中声明,也可以通过代码(作为 BroadcastReceiver对象)动态生成,并通过调用 Context.registerReceiver()注册到系统中。 关于如何组织你的应用程序的清单文件,参见 AndroidManifest.xml 文件。 意图过滤器意图对象可以精确的指定目标组件名。如果指定了,Android将会找到该组件(基于清单文件中的声明),并激活它。但是,如果目标不是精确的名称, Android就必须定位到最适合的组件来响应意图。它将意图对象与意图过滤器的可能的目标作比较。组件的意图过滤器,可以通知Android关于该组件可处理的多种意图。象其它的组件的基本信息一样,他们也在清单文件中声明。这里是对前一个例子的扩展,为活动增加了两个意图过滤器: &&&&&&&&&&&&&&&&&&&&&&&&&&&&& android:icon="@drawable/small_pic.png"&&&&&&&&&&&&&&&&& android:label="@string/freneticLabel"&&&&&&&&&&&&&&&&& . . .& $>$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& . . .&&& 例子中的第一个过滤器 — 动作" android.intent.action.MAIN" 和分类" android.intent.category.LAUNCHER"的组合 — 这是一个普通的例子。它标记该活动可以显示在应用程序启动器(列出用户可以在设备上启动的应用程序的画面)中。也就是说,该活动是应用程序的入口点,当用户从启动器运行应用程序时看到的第一个活动。 第二个过滤器声明了一个动作,该活动可以处理特殊类型的数据。 组件可以有很多过滤器,每一个声明一种不同的能力。如果它没有任何过滤器,就只能通过提供了组件的精确名的意图来启动。 对于通过代码创建和注册的广播接收者,意图过滤器直接作为 IntentFilter 对象实例化。所有其它过滤器都通过清单文件设置。 关于意图过滤器的更多信息,参见文档 意图和意图过滤器。 活动和任务前面提到过,一个活动可以启动另一个活动,包括属于其它应用程序的活动。例如,你可能想让用户显示某个地方的地图。已经有一个活动可以完成它,那么你的应用程序要做的,只是传递包含必要信息的意图对象到 startActivity()中。地图查看器将会显示它。当用户按下回退键时,你的活动将再次出现在屏幕上。 对于用户来说,地图查看器就象是该应用程序的一部分,即使它定义于其它应用程序,运行于那个应用程序的进程。 Android通过将两个活动归入同一个任务task来维护用户体验。简单的说,任务就是用户认为的"应用程序"。它就是被安排在堆中的、有关联的一组活动。根活动是堆中用于启动任务的活动, — 一般来说,它是用户在应用程序启动器中选择的活动。堆顶部的活动是当前运行的活动 — 具有焦点,并对用户的动作作出反应。当启动另一个活动时,新活动被压入堆中;成为当前活动。前面的活动保留在堆中。当用户按下回退键时,当前活动弹出堆,前一个活动恢复为当前活动。 堆保存这些对象,如果一个任务包含两个以上的同一个活动子类的实例 —比如多个地图查看器— 每个实例在堆中有各自的入口。活动在堆中不会被重新排列,只是压入和弹出。 任务是活动的堆,不是一个类或清单文件的一个元素。因此,无法为任务中的某个独立的活动赋值。对于一个任务整体,值是赋给它的根活动的。比如下一节会谈到的"任务中的关系";值是通过设到任务的根活动中的关系取得的。 任务中的所有活动作为一个整体移动。整个任务(整个活动堆)可以被带到前台或送到后台。比如,当前任务的堆中有四个活动 —有三个在当前活动下面。用户按下HOME键、打开应用程序启动器、选择一个新的应用程序(实际上就是一个任务)。当前任务转为后台运行,新任务的根活动被显示出来。过了一会儿,用户返回了HOME,并选择了之前的应用程序(前一个任务)。堆中包含四个活动的任务转为前台。当用户按下回退键时,并不显示刚刚离开的活动(前一个任务的根活动)。而是堆顶部的活动被移除,显示堆中的前一个活动。 该行为是活动和任务的缺省行为。有办法修改这些行为。活动与任务结合、任务中活动的行为,由启动活动时设置到意图对象中的标志,和清单文件中活动对应的 元素的属性来控制。请求方和应答方对该行为都有发言权。 主要的意图标志如下: FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_SINGLE_TOP主要的 属性如下: taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch alwaysRetainTaskState finishOnTaskLaunch下一节介绍这些标志和属性的用处、如何交互和它们应该如何使用。 关系和新任务默认情况下,应用程序中的所有活动之间都有关系— 因为它们有共同点,就是都属于同一个任务。但是可以使用 元素的taskAffinity属性来为活动设置单独的关系。属于不同应用程序的活动可以共享相同的关系,同一应用程序中的活动也可以拥有不同的关系。关系在两种情况下发挥作用:当意图对象包含FLAG_ACTIVITY_NEW_TASK标志来启动活动时、和活动的 allowTaskReparenting属性的值为"true"时。 FLAG_ACTIVITY_NEW_TASK标志如前所述,新的活动默认运行于调用 startActivity()的活动的任务中。它被放入与调用者相同的堆中。如果传递给 startActivity()的意图对象包含 FLAG_ACTIVITY_NEW_TASK标志,系统将为该新活动寻找不同的任务。看到该标志就会想到它表示新任务。不过它有可能不是。如果有既存的任务与该新活动有相同的关系,该活动会被并入该任务。如果没有这样的任务,则开始一个新任务。allowTaskReparenting属性如果一个活动的 allowTaskReparenting属性被设成了" true",则它可以从启动它的任务移动到与它具有相同关系的前台任务中。例如,一个报告选定地点的天气状况的活动,属于某个旅行应用程序的一部分。它与同一应用程序的其它活动具有相同的关系(默认关系),并且它允许重置从属关系。你的一个活动启动了天气报告程序,那么它与你的活动属于同一个任务。当旅行应用程序接下来运行时,天气报告程序会被重新指定为在旅行应用程序的任务中显示信息。如果一个.apk 文件包含两个以上的"应用程序"(以用户的角度),你应该为每个活动集合准备不同的关系。 运行模式元素的 launchMode属性可以接受四种运行模式: " standard"(缺省模式) "singleTop" "singleTask" "singleInstance"各模式间的差别有如下四点: 对意图做出反应的活动在哪个任务中运行 对于"standard"和" singleTop"模式,它就是发出意图的任务(调用 startActivity()的任务) — 除非意图对象中包含 FLAG_ACTIVITY_NEW_TASK标志。这种情况下,象前一节 关系和新任务中讲的一样,会选择不同的任务。 对应的"singleTask "和" singleInstance"模式标记该活动总是作为任务的根。它们定义的任务永远不会在其它任务中运行。 是否可以运行活动的多个实例。"standard"或" singleTop "模式的活动可以实例化多次。它们可以属于多个任务,一个任务中也可以存在多个相同活动的实例。 对应的"singleTask "和"singleInstance” 模式的活动被限制为只能拥有一个实例。当这样的活动是任务的根活动时,该限制意味着,在该设备上不会同时存在两个以上的相同任务的实例。 实例是否允许其任务中存在其它活动。"singleInstance "模式的活动作为其任务中唯一的活动,如果它启动其它活动,那么被启动的活动会被分配到其它任务中运行,忽略其运行模式 — 就象在意图中指定了 FLAG_ACTIVITY_NEW_TASK标志一样。所有的其它方面,"singleInstance"模式与"singleTask"模式相同。另外三种模式允许一个任务中存在多个活动。" singleTask"活动总是作为任务的根活动,但它可以在自己的任务中运行其它活动。" standard"和" singleTop"的活动可以在堆的任何位置上运行。 为了处理新意图是否运行类的新实例。对于默认的" standard "模式,响应每个新意图都会创建新的实例。每个实例只响应一个意图。对于" singleTop"模式,如果它位于目标任务的活动堆的顶层,既存的类的实例将会重用,来处理新的意图。如果它不在顶层,将不会被重用。而是创建一个新的实例,压入堆中,来处理新的意图。 例如,假设一个任务的活动堆中包含根活动A、活动B、活动C、和顶层活动D,堆中的内容为A-B-C-D。在收到一个活动D的意图时。如果D是默认的"standard"运行模式,类的新实例将会运行,堆变成了A- B-C-D-D。可是,如果D的运行模式是" singleTop",既存实例会处理新意图(因为它在堆的顶部),堆保持为A-B-C-D。 另一种情况,如果到达的是B的意图,无论B的模式是"standard"还是" singleTop ",一个B的新实例都会被创建 (因为B不在堆的顶部),堆变成了A-B-C-D-B。 如上所述,对于" singleTask"或" singleInstance"的活动,不会出现多于一个实例的情况。所以,该实例会处理新的意图。" singleInstance"活动总是位于堆的顶层(因为它是任务的唯一活动),因此它总是会响应意图。在堆中,"singleTask "活动可能有也可能没有其它活动在它的上面。如果有的话,它将不能处理意图,意图将被丢掉。(虽然意图被丢掉了,但是该任务也会象正常处理意图一样被带到前台。) 当既存的活动被要求处理新意图时,意图对象通过调用 onNewIntent()传入活动。(被调用的活动可以通过调用 getIntent()取得。) 注意,当创建一个新实例来处理活动时,用户可以按回退键返回前一个状态(前一个活动)。但是,当活动的一个既存的实例来处理新意图时,用户不能通过按回退键返回收到新意图前的状态。 更多关于运行模式的信息,参见 元素。 堆的清除如果用户离开任务时间较长,系统会清除任务中根活动以外的所有活动。当用户再次返回时,只能看到最初的活动。这样做的原因是,一段时间之后用户可能不关心之前做了什么,而是返回该任务做一些新的事情。 这是默认情况。有一些活动属性可以用于控制和修改这些行为: alwaysRetainTaskState属性如果任务的根活动的该属性被设为" true",上述默认行为不会发生。任务会保留堆中的所有活动,即使过了很长时间。clearTaskOnLaunch属性如果任务的根活动的该属性被设为" true",当用户离开任务再返回时,堆将清除到只剩任务的根活动。换句话说,它与 alwaysRetainTaskState完全相反。用户总是返回到任务的初始状态,即使离开一瞬间。finishOnTaskLaunch属性该属性与 clearTaskOnLaunch类似,但它的操作对象是单独的活动、而不是整个任务。并且它可以应用与任何活动,包括根活动。当它被设为"true "时,活动只保留当前状态。如果用户离开后再返回任务,它将不再存在。有其它办法可以强制从堆中清除活动。如果意图对象包含 FLAG_ACTIVITY_CLEAR_TOP标志,并且目标任务中包含可以处理意图的活动的实例,则该实例上层的活动都会被清除,以使它处于堆的顶层,来响应意图。如果活动本身的运行模式是" standard",则它也会被从堆中清除,并运行新实例来处理收到的意图。这是因为运行模式为" standard "的活动总是创建新实例来响应新的意图。 FLAG_ACTIVITY_CLEAR_TOP经常与 FLAG_ACTIVITY_NEW_TASK一起使用。当同时使用时,意味着在其它任务中找到既存活动,并使其可以响应意图。 任务的启动通过为活动指定一个动作为“ android.intent.action.MAIN”、分类为“ android.intent.category.LAUNCHER ”的意图过滤器,可以将活动设为任务的入口。(前面的意图过滤器一节中有这种过滤器的例子。)这种过滤器会在应用程序启动器中显示一个图标和标签,让用户可以启动一个任务或者返回已运行的任务。 第二个能力比较重要:用户必须能在离开任务后还可以回到该任务。正因为如此,会导致初始化新任务的两种运行模式,“singleTask” 和“singleInstance”,只有在活动具有 MAIN和 LAUNCHER过滤器时才可以使用。想象一下,如果没有上述过滤器的话会是什么情况:意图启动了一个“singleTask”的活动,初始化了一个新任务,用户用户在该任务上操作了一段时间。之后用户按下了HOME键,这时该任务被挡在了主屏幕的后面。因为它没有出现在应用程序启动器中,因此用户无法返回该任务。 它与启动带时带有FLAG_ACTIVITY_NEW_TASK标志有些许不同。如果该标志导致启动了新的任务,并且用户按下了HOME键,离开了该任务。则必须有办法使用户通过某种途径回到该任务。一些活动(比如提示管理器)总是在其它的任务中启动活动,从不在自己的任务中启动。因此,其总是将 FLAG_ACTIVITY_NEW_TASK标志放入意图,传给startActivity()。如果你的活动可以由外部活动来调用,你可以使用该标志。注意,一定要保证用户可以返回其启动的任务。则必须有办法使用户通过某种途径回到该任务。 在不想让用户返回活动时,可以将的元素finishOnTaskLaunch 设为“true”。参见前面的堆的清除。 进程和线程当应用程序的第一个组件需要运行时,Android会为其启动一个包含一个线程的Linux进程。默认情况下,该应用程序的所有组件都会在该进程的该线程中运行。 然而,你可以使组件运行于其它进程,或者为任何进程启动一个线程。 进程进程是由清单文件控制的,组件运行的地方。组件元素 — 、、 和 — 都有一个process属性,用于指定组件在哪个进程中运行。这些属性可以设为每个组件有其独立的进程,也可以设成一些组件共享一个进程,其它的独占一个进程。也可以设置成,不同应用程序的组件在同一进程中运行 — 只要这些应用程序是由同一个作者签名并共享同一个Linux用户ID。 也有一个process属性用于设置应用到所有组件的默认值。 所有的组件都在指定的进程的主线程中运行,系统调用该线程中的组件。不同的线程不会创建不同的实例。因此,响应用户动作的方法比如View.onKeyDown() 以及后面的组件生命周期 中讨论的生命周期消息,总是只在进程的主线程中发生。这意味着,由系统调用的组件不应该长时间运行或阻断其它操作(比如网络操作、循环运算),因为这将阻碍进程中其它组件的运行。象下面的 线程中讨论的那样,你可以为耗时的操作分配单独的线程。 当更贴近用户的进程需要内存,并且内存不足时,Android可以在某一时点停止某个进程的执行。进程中的应用程序组件也被消毁。当它们再次运行时,进程重新启动这些组件。 当决定哪个进程被终止时,Android评估它们对用户的重要度。例如,与包含用户可见的活动的进程相比,包含用户不可见的活动的进程更容易被终止。因此,决定是否终止一个进程的执行,依赖于运行于该进程的组件的状态。这些状态作为组件生命周期一节的主题。 线程虽然你可以限制你的应用程序只在一个进程中执行,也会有需要其它线程来做一些后台处理。因为用户界面应该总是能够快速响应用户的动作,因此运行活动的线程不能同时运行象网络下载这样的耗时的操作。任何不能立即完成的操作都应该在不用的线程中执行。 线程是在代码中,使用标准JavaThread 对象创建的。 Android提供了一些方便的工具来管理线程 —Looper 用于在线程中执行消息循环、 Handler 用于处理消息、HandlerThread 用于设置一个带有消息循环的线程。 远程过程调用Android拥有轻量级的远程调用机制 (RPC) — 方法在本地调用,在远程执行(在其它进程中),结果返回给调用者。这意味着将方法调用及其附带的数据分解为操作系统可以理解的形式,将其由本地进程和地址空间传送到远程进程和地址空间中,在远程重新装配并执行该调用。返回值沿着相反的方向传递。Android提供了实现该机制的所有代码,因此你只需要关注于如何定义和实现该RPC接口本身。 RPC接口只能包含方法。所有的方法都是同步执行的(本地方法被阻断,直到远程方法结束),即使没有返回值。 简而言之,该机制的流程如下:你由使用简单的IDL(接口定义语言)定义要实现的RPC接口。根据接口的定义, aidl 工具生成本地和远程进程必要的Java接口的定义。它包含下图所示的两个内部类:
内部类中包含管理你用IDL生成的远程过程调用需要的所有代码。两个内部类都实现了IBinder 接口。其中一个在本地由系统内部使用,写代码时可以忽略它。另一个叫做 Stub,扩展自Binder 类。作为对执行IPC调用的内部代码补充,它包含你在RPC接口中声明的方法。象图中说明的那样,你应该继承Stub来实现这些方法。 一般远程过程由服务来管理(因为服务可以通知系统关于进程和它连接的其它进程的信息)。它既有aidl。服务的客户端只有由aidl生成的接口文件。 接下来是服务和其客户端是如何建立连接的: 服务的客户端(为位于本地)应该实现onServiceConnected() 和onServiceDisconnected() 方法,这样它们就可以在成功与远程服务建立或断开连接后收到消息。它们应该调用bindService() 来设置连接。 服务的onBind() 方法应该被实现用作根据收到的意图(传入bindService()的意图),决定接受或拒绝连接。 如果连接被接受,它返回一个Stub的子类。如果服务接受了连接,Android调用客户端的onServiceConnected() 方法并传入一个IBinder对象,由服务管理的Stub子类的代理。通过该代理,客户端可以调用远程服务。 上述简单的描述忽略了一些RPC机制的细节。更多信息参见用AIDL设计远程接口和IBinder 类的描述。 线程安全方法一些情况下,你实现的方法可能被一个以上的线程调用,因此它必须是线程安全的。 这对于可以远程调用的方法,这是完全正确的—比如前一节讨论的RPC机制。当从IBinder的同一进程调用IBinder中实现的方法时,该方法将在掉调用者的线程中执行。然而,当该调用来自另一个进程时,该方法执行的线程是从由Android维护与IBinder处于相同进程的进程池中选择的;它不会在进程的主线程中执行。例如,服务的进程的主线程中的onBind() 方法被调用,onBind()返回的对象(比如实现了RPC方法的Stub子类)中实现的方法会在池中的线程中被调用。因为服务可以有一个以上的客户端,所以同时可以有一个以上的线程在执行同一个IBinder方法。因此,IBinder的方法必须是线程安全的。 同样,内容提供者可以接受来自其它进程的数据请求。虽然ContentResolver和ContentProvider类隐藏了如何管理进程间通信的细节,但是相应这些请求的ContentProvider方法— query()、 insert()、 delete()、 update()和 getType() —是从内容提供者进程的线程池中被调用的。因为这些方法可以同时从多个线程中调用,所以它们也必须是线程安全的。 组件生命周期应用程序组件具有生命周期—从Android生成它们用于响应一个意图开始,到实例被销毁为止。在这期间,它们可能有时处于激活状态,有时处于非激活状态,以及活动对用户是否可见。本节讨论活动、服务和广播接受器的生命周期—包括它们生存期间的状态、通知状态变化的方法、以及这些状态对实例的销毁和所在进程是否被中止的可能的影响。 活动的生命周期活动有三种状态:激活状态或者运行状态,当它在屏幕的前台显示时(在当前活动堆的顶层)。就是具有用户操作焦点的活动。 暂停状态,如果活动已经失去焦点、但是对用户依然可见。就是说另外的活动在它上面,但是它是透明的或者没有占满整个屏幕,通过它还可以看到暂停的活动。暂停的活动处于完全的生存状态(它维护着所有的状态和成员信息,保持着属于它的窗口管理器)。但是当系统内存极低时会被杀调。 停止状态,如果它被其它活动完全遮挡。它仍然保持着所有的状态和成员信息。然而它对用户不可见,因此窗口被隐藏,当其它地方需要内存时,它将被系统杀掉。 如果活动处于暂停或停止状态,系统可以通知它结束运行(调用的它的 finish()方法),或者简单的杀掉进程。当它再次呈现给用户时,它必须重新启动并恢复到之前的状态。 当活动的状态发生变化时,系统通过调用如下保护方法来通知该变化: void onCreate(Bundle savedInstanceState) void onStart() void onRestart() void onResume() void onPause() void onStop() void onDestroy()这些方法都是钩子,你可以重写它们,在状态变化时做一些适当的工作。所有的活动必须实现 onCreate() ,当对象首次实例化时做一些初始设置。很多活动会实现onPause() ,用于提交数据和准备结束与用户的交互。 调用父类任何活动实现的生命周期方法都应该首先调用父类的该方法。例如: protected void onPause() {&&& super.onPause();&&& . . .}这七个方法定义了活动的整个生命周期。实现它们,你可以监视三层嵌套的循环: 活动的整个生命周期从第一个调用onCreate() 开始,直到最后调用onDestroy()为止。活动在onCreate()中做所有“全局“状态的设置,在onDestroy()中释放所有剩余的资源。例如,如果有一个线程在后台从网络上下载数据,它可能在onCreate()中创建该进程,在 onDestroy()中停止该进程。
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-}

我要回帖

更多关于 java封装 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信