Android开发-基本概念小整理(三)为了面试的小伙伴们所准备~~

转载请注明出处: http://blog.csdn.net/iwanghang/

我正在参加CSDN 2016博客之星评选,希望得到您的宝贵一票~
http://blog.csdn.net/vote/candidate.html?username=iwanghang
请为我投票,谢谢 ~~
如果没有CSDN账号 直接使用微信/QQ/微博登陆 就能投票了~~

46.什么是ANR 如何避免它?

NR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:
对输入事件(如按键、触摸屏事件)的响应超过5秒。
意向接受器(intentReceiver)超过10秒钟仍未执行完毕。
Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intentbroadcast)。
因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和onResume()等更应如此。潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束-- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

47.如何将SQLite数据库(dictionary.db文件)与apk文件一起发布?

可以将dictionary.db文件复制到Eclipse Android工程中的resaw目录中。所有在resaw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到resaw目录中

48.如何将打开res aw目录中的数据库文件?

在Android中不能直接打开res aw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource方法获得resaw目录中资源的InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。

49.Android引入广播机制的用意?

a:从MVC的角度考虑(应用程序内)
其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。
b:程序间互通消息(例如在自己的应用程序内监听系统来电)
c:效率上(参考UDP的广播协议在局域网的方便性)
d:设计模式上(反转控制的一种应用,类似监听者模式)

50.如果后台的Activity由于某种原因被系统回收,如何在回收之前保存当前状态。

这个知识点使用描述的方式来回答的,同样问题,我们在基本概念小整理(一)的17题问过了,那边是用代码回答的。
onSaveInstanceState().
程序中的某一个ActivityA 在运行时,主动或被动的运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成以后又回来找A,这个时候有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被回收的就直接执行onResume(),跳过onCreate()。

51.Android 事件分发机制原理。

1、 Android事件分发是先传递到ViewGroup,再由ViewGroup传递到View的。
2、 在ViewGroup中可以通过onInterceptTouchEvent方法对事件传递进行拦截,onInterceptTouchEvent方法返回true代表不允许事件继续向子View传递,返回false代表不对事件进行拦截,默认返回false。
3、子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件。


52.Android 绘图机制原理。

View树的绘制是一个递归的过程,从ViewGroup一直向下遍历,直到所有的子view都完成绘制,View树的源头是ViewRoot。
ViewRoot中包含了窗口的总容器DecorView,ViewRoot中的performTraversal()方法会依次调用decorView的measure、layout、draw方法,从而完成view树的绘制。
invalidate()方法会导致View树的重新绘制,而且view中的状态标志mPrivateFlags中有一个关于当前视图是否需要重绘的标志位DRAWN,也就是说只有标志位DRAWN置位的视图才需要进行重绘。当视图调用invalidate()方法时,首先会将当前视图的DRAWN标志置位,之后有一个循环调用parent.invalidateChildinParent(),这样会导致从当前视图依次向上遍历直到根视图ViewRoot,这个过程会将需要重绘的视图标记DRAWN置位,之后ViewRoot调用performTraversals()方法,完成视图的绘制过程。

53.Android WindowManager。

WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:addView()、 updateViewLayout()、removeView()。
在WindowManager中还有一个重要的静态类LayoutParams.通过它可以设置和获得当前窗口的一些属性。
我们先来看看addView()方法,在addView中,会利用LayoutParams获得window的View属性,并为每个window创建ViewRoot,ViewRoot是View和WindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRoot的setView()方法,ViewRoot实现了View和WindowManager之间的消息传递。在将主窗口添加到WindowManger时,它首先会建立一个代理对象:
wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系。br />ViewRoot通过IWindowSession把窗口添加到WindowManager中。ViewRoot继承了Handler,实际上它的本质就是一个Handler,窗口中View的事件处理、消息发送、回调等将通过ViewRoot来处理。
这样就完成了把窗口添加到WindowManager中,并交由WindowManager来管理窗口的view、事件、消息收集处理等。

54.Android 进程间通信方式。

进程:在 Android 里面,进程是一组组件的集合。默认下,同一个应用的所有组件都运行在同一个进程中并且大多数程序不必改变这一状况.然而,如果你非要与众不同,也可以通过修改 AndroidManifest.xml 文件中修改四大组件(activity,service,receiver和provider)的process 属性来指定该组件运行在哪一个进程里。
由于 Android 本身设计的原因,进程间的数据是无法直接共享的,如果我们需要知道不同进程间的一些数据,就需要进行进程间通信操作。下面总结了以下进程间通信的一些方法。
1、Intent数据共享
Activity:
Intent intent = new Intent();
intent.setClassName("otherpackage","OtherActivity");
intent.putExtra("key","value");
startActivity(intent);
OtherActivity:
String value = getIntent().getStringExtra("key");
2、Broadcast广播跨进程通信
Intent broadcast = new Intent("my.broadcast.action");
broadcast.putExtra("key","value");
sendBroadcast(broadcast);
3、Content Provider
比如获取一个联系人的详情。联系人的详情时存在系统里面的,我们的应用一定不会和系统程序在一个进程,Content Provider 很明显就是一个跨进程通信的方法。
4、AIDL
AIDL(Android Interface Definition Language)Android接口定义语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。
5、Messnger
们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。
6、文件
通过读写同一个文件的确是可以做到进程间通信的。

55.你是怎么设计项目架构的?

经典架构有MVC,MVP,MVVM,CLEAN等。
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
MVP全名是Model View Presenter,是模型(model)-视图(view)-表示器(presenter)的缩写。
所有架构,都是为了解耦,提高维护性。
解耦可在生产中实际效果是,把一个大工程,拆分成多个小工程,每个工程之间功能相互独立,可单独测试。把单线程变成多线程,一个人一年的工作量,拆成12个人,一个月就能做完。每个人只专注于自己那部分,对于大项目,或者工期紧的项目是非常重要的。要掌握好度,简单的功能无需再分。


56.BaseActivity、BaseFragment怎么设计?

如果是只有一个Activity的App就没有必要写BaseActivity,大于一个一般可以写BaseActivity。
每个Activity通常都是绑定视图,绑定控件,监听控件,获取Bundle,跳转Activity还有一些很有些烦人的小功能如:Toast,findViewById,我们都可以封装一层简化他们的使用。
不仅是Activity要搞一个基类,Fragment也要搞一个基类,这样可以大大减少重复代码,而且管理起来还比较容易,保持了样式的一致,也要预留个性化相应的方法。

57.你项目中的package划分,是按照层次划分的呢,还是按照功能划分的呢?

如果涉及团队协作开发,建议按模块划分。因为业务模块之间的耦合性相对于层级的耦合性要低,这样程序员在开发模块时,基本上要开发action、service、orm,这样开发的接触面比较全,而且基本上不需要与其它模块进行交互,减少沟通交流时间,能提高开发效率。如果按照层级划分,那么多人开发时,会存在action依赖service,而service由别人开发,会涉及到交流、沟通(如:action需要的业务方法,需要先告诉service开发人员……等等若干情况)

58.Android OOP AOP。

OOP,即Object Oriented Programming,面向对象编程。
AOP,即Aspect Oriented Programming,面向切向编程。
OOP,问题或者功能都被划分到一个一个的模块里边。每个模块专心干自己的事情,模块之间通过设计好的接口交互。OOP的精髓是把功能或问题模块化,每个模块处理自己的家务事。但在现实世界中,并不是所有问题都能完美得划分到模块中。有些功能是横跨并嵌入众多模块里的,比如打印日志,比如统计某个模块中某些函数的执行时间等。这些功能在各个模块里分散得很厉害,可能到处都能见到。
AOP的目标是把这些功能集中起来,放到一个统一的地方来控制和管理。如果说,OOP如果是把问题划分到单个模块的话,那么AOP就是把涉及到众多模块的某一类问题进行统一管理。比如我们可以设计两个Aspects,一个是管理某个软件中所有模块的日志输出的功能,另外一个是管理该软件中一些特殊函数调用的权限检查。




转载请注明出处: http://blog.csdn.net/iwanghang/



欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式

微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值