2016年03月25日
1 Android的线程
2 Android是怎么处理UI和耗时操作的,不同方式的优缺点
主要有三种方法,一为Handler,二为AsyncTask,三为自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui;
handler机制是,在主线程中创建handler对象,
当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用handler的sendMessage,post等方法,更新ui界面;
AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息。
自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui,这种方法需要把context对象强制转换成activity后使用
handler机制的优点是 结构清晰,功能明确,但是代码过多;
asyncTask简单,快捷,但是可能会新开大量线程,消耗系统资源,造成FC
第三种方法最好用,代码也非常简单,只是需要传递context对象
4.广播机制:通过系统广播或者自定义的广播去
实现UI线程与耗时操作线程之间的通信
优点:实现简单
缺点:不利于调试,且消息传递不够灵活,会存在安全问题
5 EventBus:EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。
比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现
优点:针对一个进程,解耦
缺点:大量使用会不利于调式
3 Intent传递数据时,下列的数据类型哪些可以被传递
正确答案: A B C D
Serializable
CharSequence
Parcelable
Bundle
intent可以传递8种基本数据类型和2个实现序列化和parcelable接口的2个对象.实现序列化的对象存放在本地文件,实现
parcelable的对象存放在内存中.
Serializable :将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用ObjectInputStream 和 ObjectOutputStream 进行对象的读写。
charsequence :
在JDK1.4中,引入了CharSequence接口,实现了这个接口的类有:CharBuffer、String、StringBuffer、StringBuilder这个四个类。
CharBuffer为nio里面用的一个类,String实现这个接口理所当然,StringBuffer也是一个 CharSequence,StringBuilder是Java抄袭C#的一个类,基本和StringBuffer类一样,效率高,但是不保证线程安 全,在不需要多线程的环境下可以考虑。
提供这么一个接口,有些处理String或者StringBuffer的类就不用重载了。但是这个接口提供的方法有限,只有下面几个:charat、length、subSequence、toString这几个方法,感觉如果有必要,还是重载的比较好,避免用instaneof这个操作符。
Parcelable :
android提供了一种新的类型:Parcel。本类被用作封装数据的容器,封装后的数据可以通过Intent或IPC传递。 除了基本类型以
外,只有实现了Parcelable接口的类才能被放入Parcel中。
是GOOGLE在安卓中实现的另一种序列化,功能和Serializable相似,主要是序列化的方式不同
Bundle:Bundle是将数据传递到另一个上下文中或保存或回复你自己状态的数据存储方式。它的数据不是持久化状态。
4 android中有三种菜单
(1)选项菜单Options menus :一个Activity只能有一个选项菜单,在按下Menu键时,显示在屏幕下方。
(2)上下文菜单Context menus :为Activity中的任何一个视图注册一个上下文菜单,“长按”出现。
(3)弹出式菜单Popup menus :依赖于Activity中的某个一个视图。
重写 onCreateContextMenu 用以创建上下文菜单重写 onContextItemSelected 用以响应上下文菜单 重写 onCreateOptionsMenu 用以创建选项菜单重写 onOptionsItemSelected 用以响应选项菜单
5getReadableDatabase()和getWriteableDatabase()都可以得到一个可既可以读又可以写的数据库对象,不同的是,当磁盘空间满了之后,getReadableDatabase()得到的是一个只读的对象,而getWriteableDatabase()则会抛出异常。
6 Activity生命周期
7 一个GLSurfaceView类 , 具有以下特点 :
1.管理一个平面, 这个平面是一个特殊的内存块 , 它可以和 android 视图系统混合 .
2.管理一个EGL 显示 , 它能够让 OpenGL 渲染到一个平面 .
3.接受一个用户提供的实际显示的Renderer 对象 .
4.使用一个专用线程去渲染从而和UI 线程解耦 .
5.支持on-demand 和连续的渲染.
6.可选的包, 追踪 和 / 或者错误检查这个渲染器的 OpenGL 调用 .
8 Android中Looper的实现原理,为什么调用Looper.prepare()就在当前线程关联了一个Looper对象,它是如何实现的。
1、线程间通信机制
首先,looper、handler、messagequeue三者共同实现了android系统里线程间通信机制。如在A、B两个子线程之间需要传递消 息,首先给每个子线程绑定一套handler、looper、messagequeue机制,然后这三个对象都与其所属线程对应。然后A线程通过调用B线 程的Handler对象,发送消息。这个消息会被Handler发送到B线程的messagequeue中,而属于B线程的Looper对象一直在for 循环里无限遍历MessageQueue, 一旦发现该消息队列里收到了新的消息,就会去对消息进行处理,处理过程中会回调自身Handler的heandleMessage方法。从而实现了不同线 程间通信。
2、Looper实现原理
Looper类里包含一个消息队列对象和一个线程对象。当创建Looper时,会自动创建一个消息队列,同时将内部线程对象指向创建Looper的线程。 当开启Looper后(looper.loop()),会自动进入无限for循环中,不断去遍历消息队列,如果没有消息则阻塞,有消息则回调 handler的handlemessage方法进行处理。
3、Looper.prepare()
首先,要使用Looper机制一般会在当前线程中创建Handler对象,里面会自动创建一个looper对象和消息队列,这里面的消息队列属于当前线程 空间。但此时的looper还不会去遍历,也没有绑定到当前线程。其中,looper对象内部也包含一个空消息队列对象和空线程。通过 Looper.prepare()方法,先让该消息队列指向当前线程的消息队列,让空线程也指向当前线程。从而实现了绑定。
9 Android系统对下列哪些对象提供了资源池
正确答案: A C 你的答案: A B C D(错误)
Message
Thread
AsyncTask
Looper
A.Message提供了消息池,有静态方法Obtain从消息池中取对象;
B.Thread默认不提供资源池,除非使用线程池ThreadPool管理;
C.AsynTask是线程池改造的,池里 默认提供(核数+1)个线程进行并发操作,最大支持(核数 * 2 + 1)个线程,超过后会丢弃其他任务;
D.Looper,每个Looper创建时创建一个消息队列和线程对象,也不是资源池;
因此答案为AC
10 android的自动恢复功能能够完成?
正确答案: D 你的答案: D(正确)
恢复地址簿
修复丢失的文字信息
恢复删除的信息
恢复备份设置和数据来重新安装程序
11 Activty和Task的启动模式有哪些?
standard、singleTop、singleTask、singleInstance
“拿来主义”standard模式。哪里需要调用我我就去哪里,可以多次实例化,可以几个相同的Activity重叠。
“拒绝堆叠”singleTop模式。可以多次实例化,但是不可以多个相同的Activity重叠,当堆栈的顶部为相同的Activity时,会调用onNewIntent函数。
“独立门户”singleTask模式。同一个应用中调用该Activity时,如果该Activity没有被实例化,会在 本应用程序的Task内实例 化,如果已经实例化,会将Task中其上的Activity销毁后,调用onNewIntent;其它应用程序调用该Activity时,如果该 Activity没有被实例化,会创建新的Task并实例化后入栈,如果已经实例化,会销毁其上的Activity,并调用onNewIntent。一句 话,singleTask就是“独立门户”,在自己的Task里,并且启动时不允许其他Activity凌驾于自己之上。
“孤独寂寞”singleInstance模式。加载该Activity时如果没有实例化,他会创建新的Task后,实例化入栈,如果已经存在,直接调用 onNewIntent,该Activity的Task中不允许启动其它的Activity,任何从该Activity启动的其他Activity都将被 放到其他task中,先检查是否有本应用的task,没有的话就创建。
12 AVD不支持蓝牙模拟
13 当 Activity 被消毁时,如何保存它原来的状态
实现 Activity 的 onSaveInstanceState()方法
14
Android数据持久化主要有几种:1.保存到Shared Preferences
2.保存到手机内存 3.保存到SDCard中 4.保存到SQlite数据库中
15 对文件名为Test.java的java代码描述正确的是()
class
Person {
String
name =
"No name"
;
public
Person(String nm) {
name
= nm;
}
}
class
Employee extends Person {
String
empID =
"0000"
;
public
Employee(String id) {
empID
= id;
}
}
public
class
Test {
public
static
void
main(String args[])
{
Employee
e =
new
Employee(
"123"
);
System.out.println(e.empID);
}
}
正确答案: C 你的答案: B(错误)
输出:0000
输出:123
编译报错
输出:No name