苏州大学Android[韩冬]期末复习

2020-05-01 11:54

《Android应用开发》复习题:

1. Android的体系结构是怎样的?请简要加以说明。

Android 的系统架构采用了分层架构的思想。 从上层到底层共包括四层:

应用层、应用框架层、 系统运行库层、 Linux 内核层。

2. Android程序结构是怎样的?请简要加以分析。

? ? ? ? ?

src目录:java 源代码

gen目录:BuildConfig.java、R.java

res目录:res 目录是资源目录,可以存放应用使用到的各种资源,如 XML 界面文件、图片、数据等。

assets目录:assets 资源目录一般可用于存放 html 文件、数据库文件、 javascript 文件等, 还有原始格式的文件.

AndroidManifest.xml:列出了应用程序提供的功能,开发好的各种组件需要在此文件中进行配置,当应用使用到系统内置的应用还需在此文件中声明使用权限

3. Handler消息传递机制是怎样的?试以“计时器”的编程举例加以说明。

首先需要在主线程当中创建一个 Handler 对象,并重写handleMessage()方法。然后当子线程中需要进行 UI 操作时,就创建一个 Message 对象,并通过 Handler 将这条消息发送出去。之后这条消息会被添加到 MessageQueue 的队列中等待被处理,而 Looper 则会一直尝试从 MessageQueue 中取出待处理消息,最后分发回 Handler的 handleMessage()方法中。由于 Handler 是在主线程中创建的,所以此时 handleMessage()方法中的代码也会在主线程中运行,于是我们在这里就可以安心地进行 UI 操作了。

一条 Message 经过这样一个流程的辗转调用后,也就从子线程进入到了主线程,从不能更新 UI 变成了可以更新 UI,整个异步消息处理的核心思想也就是如此。

4. 什么是进程内服务?请编程加以说明。

在同一个进程下调用的服务,(通常情况下)即在一个应用程序下的服务。

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()方法就可以了,这也是Unbind Service按钮的点击事件里实现的逻辑。

5. 什么是跨进程服务?请编程加以说明。

通过一个应用程序(客户端)的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 定义的“ android.intent.action.AIDLService”这个标识符来绑定我们所需要的服务,这样客户端和服务端就实现了通信的连接,我们就可以调用 IPerson 中的 hello 方法了。

使用了MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成了MyAIDLService对象,接下来就可以调用在MyAIDLService.aidl文件中定义的所有接口了。

IPerson 接口中的抽象内部类 Stub 继承 android.os.Binder 类并实现 IPerson 接口, 其中比较重要的方法是 asInterface(IBinder)方法,该方法会将 IBinder 类型的对象转换成 IPerson 类型,必要的时候生成一个代理对象返回结果。

6. 如何发送广播?请编程加以说明。

?

因此新建一个 MyBroadcastReceiver 继承自 BroadcastReceiver,代码如下所示:

public class MyBroadcastReceiver extends BroadcastReceiver { @Override

public void onReceive(Context context, Intent intent) { Toast.makeText(context, \Toast.LENGTH_SHORT).show(); } }

? ?

然后在 AndroidManifest.xml 中对这个广播接收器进行注册 然后修改 MainActivity中的代码,如下所示:

public class MainActivity extends Activity { ?? @Override

protected void onCreate(Bundle savedInstanceState) { } ?? }

可以看到,我们在按钮的点击事件里面加入了发送自定义广播的逻辑。首先构建出了一个 Intent 对象,并把要发送的广播的值传入,然后调用了 Context 的 sendBroadcast()方法将广播发送出去,这样所有监听 com.example.broadcasttest.MY_BROADCAST 这条广播的广播接收器就会收到消息。此时发出去的广播就是一条标准广播。

}); ??

super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { }

@Override

public void onClick(View v) {

Intent intent = new Intent(\MY_BROADCAST\sendBroadcast(intent);

7. 如何接收系统广播消息?请编程加以说明。

其实只需要新建一个类,让它继承自 BroadcastReceiver,并重写父类的 onReceive()方法就行了。这样当有广播到来时, onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。

registerReceiver(BroadcastReceiver, intentFilter);--oncreate() unregisterReceiver(BroadcastReceiver);--ondestroy()

8. 什么是观察者模式?观察者模式的使用场景是怎样的?观察者模式的优缺点是什么?

试编程加以说明。

?

定义:定义对象间一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新 ?

使用场景: ? ? ? ?

关联行为场景。注意的是,关联行为是可拆分的,而不是组合关系。 事件多级触发场景

跨系统的消息交换场景,如消息队列的处理机制

优点: ? ?

观察者和被观察这之间是抽象耦合的 建立一套触发机制

? 缺点: ?

需要考虑下开发效率和运行效率

9. 什么是装饰模式?装饰模式的使用场景是怎样的?装饰模式的优缺点是什么?试编程

加以说明。

?

装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。 ?

装饰器模式的应用场景:( 1) 需要扩展一个类的功能。( 2) 动态的为一个对象增加功

能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。) ? ?

缺点:产生过多相似的对象,不易排错。 优点: ? ? ?

装饰类和被装饰类可以独立发展,而不会互相耦合 装饰模式是继承关系的一个替代方案

装饰模式可以动态地扩展为一个实现类的功能

10. Executor、ExecutorService和Executors的区别是什么?

?

Executor 是一个简单的标准化接口,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。根据所使用的具体 Executor 类的不同,可能在新创建的线程中,现有的任务执行线程中,或者调用 execute() 的线程中执行任务,并且可能顺序或并发执行。 ?

ExecutorService提供了多个完整的异步任务执行框架。 ExecutorService 管理任务的排队和安排, 并允许受控制的关闭。 ?

Executors 类提供大多数 Executor 的常见类型和配置的工厂方法,以及使用它们的几种实用工具方法 ?

Java里面线程池的顶级接口是 Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService。ExecutorService 继承Executor。Executors 类为创建 ExecutorService 提供了便捷的工厂方法。

11. 为什么说Executors类为创建ExecutorService提供了便捷的工厂方法?

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在 Executors 类里面提供了一些静态工厂,生成一些常用的线程池。 ( 1) newCachedThreadPool: 创建一个可缓存的线程池。如果线程池的大小超过了处理任


苏州大学Android[韩冬]期末复习.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:结题报告 课程理念下教师教学方式和学生学习方式转变的结题报告

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: