苏州大学Android【韩冬】期末复习_第1页
苏州大学Android【韩冬】期末复习_第2页
苏州大学Android【韩冬】期末复习_第3页
苏州大学Android【韩冬】期末复习_第4页
苏州大学Android【韩冬】期末复习_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

苏州大学Android【韩冬】期末复习苏州大学Android【韩冬】期末复习苏州大学Android【韩冬】期末复习xxx公司苏州大学Android【韩冬】期末复习文件编号:文件日期:修订次数:第1.0次更改批准审核制定方案设计,管理制度《Android应用开发》复习题:Android的体系结构是怎样的?请简要加以说明。

Android的系统架构采用了分层架构的思想。从上层到底层共包括四层:应用层、应用框架层、系统运行库层、Linux内核层。Android程序结构是怎样的?请简要加以分析。

src目录:java源代码gen目录:BuildConfig.java、R.javares目录:res目录是资源目录,可以存放应用使用到的各种资源,如XML界面文件、图片、数据等。assets目录:assets资源目录一般可用于存放html文件、数据库文件、javascript文件等,还有原始格式的文件.AndroidManifest.xml:列出了应用程序提供的功能,开发好的各种组件需要在此文件中进行配置,当应用使用到系统内置的应用还需在此文件中声明使用权限Handler消息传递机制是怎样的?试以“计时器”的编程举例加以说明。

首先需要在主线程当中创建一个Handler对象,并重写handleMessage()方法。然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的handleMessage()方法中。由于Handler是在主线程中创建的,所以此时handleMessage()方法中的代码也会在主线程中运行,于是我们在这里就可以安心地进行UI操作了。一条Message经过这样一个流程的辗转调用后,也就从子线程进入到了主线程,从不能更新UI变成了可以更新UI,整个异步消息处理的核心思想也就是如此。什么是进程内服务?请编程加以说明。在同一个进程下调用的服务,(通常情况下)即在一个应用程序下的服务。Service的启动有两种方式:context.startService()和context.bindService()。新建一个MyService继承自Service,并重写父类的onCreate()、onStartCommand()和onDestroy()方法。Service与activity通讯:context.bindService()我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service,这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。然后如何我们想解除Activity和Service之间的关联怎么办呢?调用一下unbindService()方法就可以了,这也是UnbindService按钮的点击事件里实现的逻辑。

什么是跨进程服务?请编程加以说明。通过一个应用程序(客户端)的Activity调用另一个应用程序(服务端)的Service为跨进程服务。由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。Android提供了AIDL工具来处理这项工作。在Android中,如果需要在不同进程间实现通信,就需要用到AIDL技术去完成。AIDL是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作。在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢显然,Java中是不支持跨进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。我们只是修改了ServiceConnection中的代码。可以看到,这里首先使用了MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成了MyAIDLService对象,接下来就可以调用在MyAIDLService.aidl文件中定义的所有接口了。ClientTest中的Activity如果想要和MyService建立关联其实也不难,首先需要将MyAIDLService.aidl文件从ServiceTest项目中拷贝过来,注意要将原有的包路径一起拷贝过来,完成后项目的结构如下图所示:这里先是对MyAIDLService.Stub进行了实现,重写里了toUpperCase()和plus()这两个方法。这两个方法的作用分别是将一个字符串全部转换成大写格式,以及将两个传入的整数进行相加。然后在onBind()方法中将MyAIDLService.Stub的实现返回。这里为什么可以这样写呢?因为Stub其实就是Binder的子类,所以在onBind()方法中可以直接返回Stub的实现。我们实现了IPerson.Stub这个抽象类的hello方法,然后再onBind(Intent)方法中返回我们的stub实例,这样一来调用方获取的IPerson.Stub就是我们的这个实例,hello方法也会按照我们的期望那样执行。我们要重写ServiceConnection中的onServiceConnected方法将IBinder类型的对象转换成我们的IPerson类型。我们再通过服务端Service定义的“ent.action.AIDLService”这个标识符来绑定我们所需要的服务,这样客户端和服务端就实现了通信的连接,我们就可以调用IPerson中的hello方法了。使用了MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成了MyAIDLService对象,接下来就可以调用在MyAIDLService.aidl文件中定义的所有接口了。IPerson接口中的抽象内部类Stub继承android.os.Binder类并实现IPerson接口,其中比较重要的方法是asInterface(IBinder)方法,该方法会将IBinder类型的对象转换成IPerson类型,必要的时候生成一个代理对象返回结果。如何发送广播?请编程加以说明。因此新建一个MyBroadcastReceiver继承自BroadcastReceiver,代码如下所示:

publicclassMyBroadcastReceiverextendsBroadcastReceiver{

@Override

publicvoidonReceive(Contextcontext,Intentintent){

Toast.makeText(context,"receivedinMyBroadcastReceiver",

Toast.LENGTH_SHORT).show();

}

}然后在AndroidManifest.xml中对这个广播接收器进行注册然后修改MainActivity中的代码,如下所示:publicclassMainActivityextendsActivity{ …… @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Buttonbutton=(Button)findViewById(R.id.button); button.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent("com.example.broadcasttest. MY_BROADCAST"); sendBroadcast(intent); } }); …… } ……}可以看到,我们在按钮的点击事件里面加入了发送自定义广播的逻辑。首先构建出了一个Intent对象,并把要发送的广播的值传入,然后调用了Context的sendBroadcast()方法将广播发送出去,这样所有监听com.example.broadcasttest.MY_BROADCAST这条广播的广播接收器就会收到消息。此时发出去的广播就是一条标准广播。如何接收系统广播消息?请编程加以说明。其实只需要新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法就行了。这样当有广播到来时,onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。registerReceiver(BroadcastReceiver,intentFilter);--oncreate()unregisterReceiver(BroadcastReceiver);--ondestroy()什么是观察者模式观察者模式的使用场景是怎样的观察者模式的优缺点是什么试编程加以说明。定义:定义对象间一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新使用场景:关联行为场景。注意的是,关联行为是可拆分的,而不是组合关系。事件多级触发场景跨系统的消息交换场景,如消息队列的处理机制优点:观察者和被观察这之间是抽象耦合的建立一套触发机制缺点:需要考虑下开发效率和运行效率什么是装饰模式装饰模式的使用场景是怎样的装饰模式的优缺点是什么试编程加以说明。装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。装饰器模式的应用场景:(1)需要扩展一个类的功能。(2)动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)缺点:产生过多相似的对象,不易排错。优点:装饰类和被装饰类可以独立发展,而不会互相耦合装饰模式是继承关系的一个替代方案装饰模式可以动态地扩展为一个实现类的功能Executor、ExecutorService和Executors的区别是什么?

Executor是一个简单的标准化接口,用于定义类似于线程的自定义子系统,包括线程池、异步IO和轻量级任务框架。根据所使用的具体Executor类的不同,可能在新创建的线程中,现有的任务执行线程中,或者调用execute()的线程中执行任务,并且可能顺序或并发执行。ExecutorService提供了多个完整的异步任务执行框架。ExecutorService管理任务的排队和安排,并允许受控制的关闭。Executors类提供大多数Executor的常见类型和配置的工厂方法,以及使用它们的几种实用工具方法Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。ExecutorService继承Executor。Executors类为创建ExecutorService提供了便捷的工厂方法。为什么说Executors类为创建ExecutorService提供了便捷的工厂方法?

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。

(1)newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能地添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

(2)newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

(3)newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

(4)newScheduledThreadPool:创建一个定长线程池,此线程池支持定时以及周期性执行任务的需求。MyBatis与JDDC相比的优势是什么?

数据库连接不再过于频繁。SQL语句比较集中SQL语句参数比较灵活支持结果映射和结果缓存。SQL重用度提高。相对安全将MyBatis引入到项目中都有哪些步骤?

(1)引入MyBatis的JAR包;(2)配置MyBatis的XML配置文件;(3)编写映射接口和SQL映射XML文件;(4)在应用中使用接口,获得结果。Fragment的生命周期是什么?试编程加以说明。

(1)当一个Fragment被创建的时候,它会经历以下状态:onAttach()→onCreate()→onCreateView()→onActivityCreated()。(2)当这个Fragment对用户可见的时候,它会经历以下状态:onStart()→onResume()。(3)当这个Fragment进入后台的时候,它会经历以下状态:onPause()→onStop()。(4)当这个Fragment被销毁了(或者持有它的Activity被销毁了),它会经历以下状态:onPause()→onStop()→onDestroyView()→onDestroy()→onDetach()。(5)一旦Activity进入Resumed状态(也就是Running状态),你就可以自由地添加和删除Fragment了。因此,只有当Activity在Resumed状态时,Fragment的生命周期才能独立地运转,其它时候是依赖于Activity的生命周期变化的。如何把Fragment加入到Activity中?试编程加以说明。

当Fragment被加入Activity中时,它会处在对应的ViewGroup中。加载方式①:通过Activity的布局文件将Fragment加入Activity加载方式②:通过编程的方式将Fragment加入到一个ViewGroup中。如何安装配置Maven请简要加以说明。

安装JDK下载Maven配置环境变量给Maven添加本地仓库配置用户范围settings.xml错误处理设置MAVEN_OPTS环境变量何为Maven坐标?何为Maven仓库?如何编写POM坐标:maven的坐标通过5个元素进行定义,其中groupId、artifactId、version是必须的,packaging是可选的(默认为jar),classifier是不能直接定义的。groupId:定义当前Maven项目所属的实际项目,跟Java包名类似,通常与域名反向一一对应。artifactId:定义当前Maven项目的一个模块,默认情况下,Maven生成的构件,其文件名会以artifactId开头,如hibernate-core-3.6.5.Final.jar。version:定义项目版本。packaging:定义项目打包方式,如jar,war,pom,zip,……,默认为jar。classifier:定义项目的附属构件,如hibernate-core-3.6.6.Final-sources.jar,hibernate-core-3.6.6.Final-javadoc.jar,其中sources和javadoc就是这两个附属构件的classifier。classifier不能直接定义,通常由附加的插件帮助生成。仓库:在Maven的术语中,仓库是一个位置(place),例如目录,可以存储所有的工程jar文件、libraryjar文件、插件或任何其他的工程指定的文件。Maven仓库有三种类型:本地(local)中央(central)远程(remote)Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。编写POM/qileilove/articles/410638.html就像Make的Makefile、Ant的build.xml一样,Maven项目的核心是pom.xml。POM(ProjectObjectModel,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。现在先为HelloWorld项目编写一个最简单的pom.xml。首先创建一个名为helloworld的文件夹,打开该文件夹,新建一个名为pom.xml的文件,输入其内容,如代码清单3-1所示。代码清单3-1HelloWorld的POM<?xml

version="1.0"

encoding="UTF-8">

<project

xmlns="/POM/4.0.0"

xmlns:xsi="/2001/XMLSchemainstance"

xsi:schemaLocation="/POM/4.0.0

/mavenv4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.juvenxu.mvnbook</groupId>

<artifactId>helloworld</artifactId>

<version>1.0SNAPSHOT</version>

<name>Maven

Hello

World

Project</name>

</project>代码的第一行是XML头,指定了该xml文档的版本和编码方式。紧接着是project元素,project是所有pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性能够让第三方工具(如IDE中的XML编辑器)帮助我们快速编辑POM。根元素下的第一个子元素modelVersion指定了当前POM模型的版本,对于Maven2及Maven3来说,它只能是4.0.0。这段代码中最重要的是包含groupId、artifactId和version的三行。这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。groupId定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如在googlecode上建立了一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp,如果你的公司是mycom,有一个项目为myapp,那么groupId就应该是com.mycom.myapp。本书中所有的代码都基于groupIdcom.juvenxu.mvnbook。artifactId定义了当前Maven项目在组中唯一的ID,我们为这个HelloWorld项目定义artifactId为helloworld,本书其他章节代码会分配其他的artifactId。而在前面的groupId为com.googlecode.myapp的例子中,你可能会为不同的子项目(模块)分配artifactId,如myapputil、myappdomain、myappweb等。顾名思义,version指定了HelloWorld项目当前的版本——1.0SNAPSHOT。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展,version会不断更新,如升级为1.0、1.1SNAPSHOT、1.1、2.0等。6.5节会详细介绍SNAPSHOT,第13章会介绍如何使用Maven管理项目版本的升级发布。最后一个name元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个POM声明name,以方便信息交流。没有任何实际的Java代码,我们就能够定义一个Maven项目的POM,这体现了Maven的一大优点,它能让项目对象模型最大程度地与实际代码相独立,我们可以称之为解耦,或者正交性。这在很大程度上避免了Java代码和POM代码的相互影响。比如当项目需要升级版本时,只需要修改POM,而不需要更改Java代码;而在POM稳定之后,日常的Java代码开发工作基本不涉及POM的修改。参考书:《Android编程权威指南》FragmentManager是如何管理fragment并将它们的视图添加到activity的视图层级结构中的?

P122-7.6android:layout_weight属性的工作原理是什么?

Android:layout_weight属性告知LinearLayout如何进行子组件的布置安排LinearLayout是分两个步骤来设置视图的宽度的第一步:LinearLayout查看layout_width属性值第二步:LinearLayoout依据layout_weight属性值进行额外的空间分配如何使用抽象activity托管fragment

P150如何使用fragmentargument试举例说明。

P169在“《Android编程权威指南》-第12章对话框”中,CrimeFragment和DatePickerFragment由同一activity托管。CrimeFragment是如何传递数据给DatePickerFragment的?DatePickerFragment又是如何返回数据给CrimeFragment的?要传递crime记录日期给DatePickerFragment,需将记录日期保存在DatePickerFragment的argumentbundle中,这样,DatePickerFragment便可直接获取到它。eq\o\ac(○,)设置目标fragment建立关联,可以将CrimeFragment设置为DataPickerFragment的目标fragmentPublicvoidsetTargetFragment(Fragmentfragment,intrequestCode)eq\o\ac(○,)传递数据给目标fragment建立CrimeFragment与DataPickerFragment间的联系之后,将数据返回给CrimeFragment。返回的日期数据将作为extra附加给Intent补充了解:androidinflater用法在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。具体作用:1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。FragmentTransaction如果需要添加、删除、替换Fragment,则需要借助FragmentTransaction对象,FragmentTransaction代表Acticity对Fragment执行的多个改变Handler“计时器”编程布局文件:<LinearLayoutxmlns:android="/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="6dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="时间:" android:layout_weight="4" android:textSize="20dp"/> <EditText android:id="@+id/txttime" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="00:00:00" android:textSize="20dp" android:layout_weight="1"/> </LinearLayout> <Button android:id="@+id/btnstart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始计时" android:layout_gravity="center_horizontal"/> <Button android:id="@+id/btnend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止计时" android:layout_gravity="center_horizontal"/></LinearLayout>功能实现Java程序中,定义了一个Runnable对象,重写了其run()方法,该方法实现间隔1秒

向Handler对象发送一条消息,Handler对象接收都消息以后设置编辑框文本,显示最新

计时。启动应用程序后,点击开始计时,设置该按钮的单击事件监听,单击事件定义了一

个接收Runnable对象的Thread,借由该Thread的start()方法来启动Runnable。点击结束

计时,设置按钮的单击事件监听,来停止Runnable。具体实现代码如下所示:publicclassMainActivityextendsActivity{TextViewtxt;Buttonbtnstart;Buttonbtnend;Dateoldtime;booleanisstop;Threadthread;Handlerhandler=newHandler(){@OverridepublicvoidhandleMessage(Messagemsg){if(msg.what==0x123){SimpleDateFormatformat=newSimpleDateFormat("HH:mm:ss");txt.setText(format.format(oldtime));}elseif(msg.what==0x456){thread.stop();}}};Runnablerunnable=newRunnable(){@Overridepublicvoidrun(){

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论