【转载】2015Android 面试题 01
1.如何避免ANR?
答:ANR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。
当出现下列情况时,Android就会显示ANR对话框了:
对输入事件(如按键、触摸屏事件)的响应超过5秒
意向接受器(intentReceiver)超过10秒钟仍未执行完毕
Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intent broadcast)。
因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和 onResume()等更应如此。
潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。
但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 -- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前 我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。
这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。
2. handler机制的原理
答 :andriod提供了 Handler 和 Looper 来满足线程间的通信。
Handler 先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
3. Android引入广播机制的用意?
答:
a:从MVC的角度考虑(应用程序内) 其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。
android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。
b:程序间互通消息(例如在自己的应用程序内监听系统来电)
c:效率上(参考UDP的广播协议在局域网的方便性)
d:设计模式上(反转控制的一种应用,类似监听者模式)
4.什么情况会导致Force Close ?如何避免?能否捕获导致其的异常?
答:一般像空指针啊,可以看起logcat,然后对应到程序中 来解决错误。
5.如何将一个Activity设置成窗口的样式。
讲点轻松的吧,可能有人希望做出来的应用程序是一个漂浮在手机主界面的东西,那么很简单你只需要设置 一下Activity的主题就可以了在AndroidManifest.xml 中定义 Activity的地方一句话:
Xml代码 1. android :theme="@android:style/Theme.Dialog"
这就使你的应用程序变成对话框的形式弹出来了,
或者Xml代码 1. android:theme="@android:style/Theme.Translucent" 就变成半透明的,
[友情提示-.-]类似的这种activity的属性可以在android.R.styleable 类的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的属性的介绍都可以参考这个类android.R.styleable
上面说的是属性名称,具体有什么值是在android.R.style中 可以看到,比如这个"@android:style/Theme.Dialog" 就对应于android.R.style.Theme_Dialog ,('_'换成'.' < --注意:这个是文章内容不是笑脸)
就可以用在描述文件 中了,找找类定义和描述文件中的对应关系就都明白了。
(简单来说直接在配置文件引入风格。追求效果的应用此用法用到挺多);
6、IntentService有何优点?
Acitivity的进程,当处理Intent的时候,会产生一个对应的Service Android的进程处理器现在会尽可能的不kill掉你 非常容易使用
(这回答其实比较。。。其实我也不知道干嘛使,因为看帮助文档就说了一个用来处理异步请求的service,工作完了自己停止。没用过,不做评价)。
7、 广播的生命周期?
广播的生命周期非常短,当发送之后intent会到AndroidManifest.xml方法中找是不是匹配的action,如果有就调用Receiver,然后获得Receiver对象,再执行onReceiver方法,这时候Receiver对象就没有用了,
当我们再次点击按钮的时候就会重新获得对象,这就是BroadcastReceiver的生命周期。
在BroadcastReceiver里不能做一些比较耗时的操作,否则会弹出ANR(Application No Response)的对话框。
如果需要完成一项耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束,BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver的所在线程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死,所以采用子线程来解决是不可靠的。
8、启动service的两种方法?有什么区别?
一种是startService(),另一种是bindService()。
这两者的区别是第一种方式调用者开启了服务,即会与服务失去联系,两者没有关联。即使访问者退出了,服务仍在运行。如需解除服务必须显式的调用stopService方法。
主要用于调用者与服务没有交互的情况下,也就是调用者不需要获取服务里的业务方法。比如电话录音。
而后者调用者与服务绑定在一起的。当调用者退出的时候,服务也随之退出。用于需要与服务交互。
9.android获取图片有哪几种方式:
方式一:
Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
- img.setImageDrawable(drawable);
方式二:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_launcher);
- img.setImageBitmap(bitmap);
方式三:
AssetManager assetManager = getResources().getAssets();
- try {
- InputStream is = assetManager.open("ic_launcher.png");
- Bitmap bitmap = BitmapFactory.decodeStream(is);
- img.setImageBitmap(bitmap);
- } catch (IOException e) {
- e.printStackTrace();
- }
方式四:
AssetManager assetManager = getResources().getAssets();
- try {
- InputStream is = assetManager.open("ic_launcher.png");
- Drawable drawable = Drawable.createFromStream(is, null);
- img.setImageDrawable(drawable);
- } catch (IOException e) {
- e.printStackTrace();
- }
当然,还有网络获取图片等方法
以下java的相关知识点: