1.android dvm 的进程和Linux的进程,应用程序的进程是否为同一个概念:

答:dvm是dalivk虚拟机。每一个android应用程序都在自己的进程中运行,都拥有一个dalivk虚拟机实例。而每一个dvm都是在linux的一个进程。所以说可以认为是同一个概念。

2.android的动画有哪几种?他们的特点和区别是什么?

答:两种,一种是tween动画,一种是frame动画。

tween动画,这种实现方式可以使视图组件移动(TranslateAnimation),放大或缩小(ScaleAnimation),旋转(RotateAnimation),透明度(AlphaAnimation)。

frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。

3.handler进制的原理:

答:android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).

1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)

2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。

3)messagequeue:用来存放线程放入的消息。

4)线程:UI thread 通常就是main thread,而android启动程序时会为它建立一个message queue.

3.1.请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系:

答:Handler获取当前线程中的looper对象,looper用来从存有Message的Message Queue里取出message,再由Handler进行message的分发和处理。

4.android view的刷新:

答:Android中对View的更新有很多种方式,使用时要区分不同的应用场合。我感觉最要紧的是分清:多线程和双缓冲的使用情况。 1).不使用多线程和双缓冲 这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。 2).使用多线程和不使用双缓冲 这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the originalthread that created a view hierarchy can touch its views. 这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Messagemsg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接调用View对象中的invalidate()方法 )。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。 3).使用多线程和双缓冲 Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。

4.1.android view,surfaceview,glsurfaceview的区别:

答:SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。 那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。 当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。 所以基于以上,根据游戏特点,一般分成两类。 1)被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。 2)主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

5.说说mvc模式的原理,它在android中的运用:

答:android的官方建议应用程序的开发采用mvc模式。何谓mvc?

  mvc是model,view,controller的缩写,mvc包含三个部分:

  l模型(model)对象:是应用程序的主体部分,所有的业务逻辑都应该写在该层。

  2视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。

  3控制器(control)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给m哦得了处理。

  android鼓励弱耦合和组件的重用,在android中mvc的具体体现如下:

1)视图层(view):一般采用xml文件进行界面的描述,使用的时候可以非常方便的引入,当然,如何你对android了解的比较的多了话,就一定 可以想到在android中也可以使用javascript+html等的方式作为view层,当然这里需要进行java和javascript之间的通 信,幸运的是,android提供了它们之间非常方便的通信实现。

  2)控制层(controller):android的控制层的重 任通常落在了众多的acitvity的肩上,这句话也就暗含了不要在acitivity中写代码,要通过activity交割model业务逻辑层处理, 这样做的另外一个原因是android中的acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。

  3)模型层(model):对数据库的操作、对网络等的操作都应该在model里面处理,当然对业务计算等操作也是必须放在的该层的

6.Activity的生命周期:

答:onCreate: 在这里创建界面,做一些数据 的初始化工作

  onStart: 到这一步变成用户可见不可交互的

onResume:变成和用户可交互 的,(在activity 栈系统通过栈的方式管理这些个Activity的最上面,运行完弹出栈,则回到上一个Activity)

  onPause: 到这一步是可见但不可交互的,系统会停止动画 等消耗CPU 的事情从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在

  onstop: 变得不可见,被下一个activity覆盖了

onDestroy: 这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方法或者是系统为了节省空间将它暂时性的干掉

6.1.横竖屏切换时候的activity的生命周期:

答:1) 新建一个activity,并把各个生命周期打印出来

2) 运行activity,得到如下信息:

onCreate()

onStart()

onResume()

3) 按ctrl+F12切换成横屏时

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()

4) 再按ctrl+f12切换成竖屏时,发现打印了两次相同的Log

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()à

onRestoreInstanceState()

onResume()

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()

5) 修改AndroidManifest.xml,把该Activity添加android:configChanges=“orientation”,执行步骤3

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()

6) 修改AndroidManifest.xml,把该Activity添加android:configChanges=“orientation”,执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()

onConfigurationChanged()

7) 把步骤5的android:configChanges=“orientation”改成android:configChanges=“orientation|keyboradHidden”,执行步骤3,就只打印onConfigChanged

onConfigurationChanged()

8) 把步骤5的android:configChanges=“orientation”改成android:configChanges=“orientation|keyboradHidden”,执行步骤4

onConfigurationChanged()

onConfigurationChanged()

总结:

1) 不设置activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。

2) 设置activity的android:configChanges=“orientation”时, 切屏会重新调用各个生命周期,切横屏、竖屏时都只会执行一次,但是竖屏最后多打印一条onConfigurationChanged()

3) 设置activity的android:configChanges=“orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged(),横屏一次,竖屏两次

再总结下整个activity的生命周期:

1) 当前activity产生事件弹出Toast和AlertDialog的时候Activity的生命周期不会有改变

2) Activity运行时按下HOME键(跟被完全覆盖一样的)

onSavaInstanceState()

onPause()

onStop()

onRestart()

onStart()

onResume()

3) 未被完全覆盖,只是失去焦点:

onPause()

onResume()

6.3.说明onSaveInstanceState() 和 onRestoreInstanceState()在什么时候被调用:

答:Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState()才会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。 另外,当屏幕的方向发生了改变, Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法。

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

当你的程序中某一个ActivityA在运行时中,主动或被动地运行另一个新的ActivityB 这个时候A会执行

Java代码

publicvoidonSaveInstanceState(BundleoutState){

super.onSaveInstanceState(outState);

outState.putLong("id",1234567890);

}

B完成以后又会来找A,这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回 收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数savedInstanceState,没被收回的就还是onResume就好了。

savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。

Java代码

if(savedInstanceState!=null){ longid=savedInstanceState.getLong("id"); }

就像官方的Notepad教程里的情况,你正在编辑某一个note,突然被中断,那么就把这个note的id记住,再起来的时候就可以根据这个id去把那个note取出来,程序就完整一些。这也是看你的应用需不需要保存什么,比如你的界面就是读取一个列表,那就不需要特殊记住什么,哦,没准你需要记住滚动条的位置...

6.5.如何退出Activity 对于单一Activity的应用来说,退出很简单,直接finish()即可。当然,也可以用killProcess()和System.exit()这样的方法。现提供几个方法,供参考:
1、抛异常强制退出:该方法通过抛异常,使程序ForceClose。验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出ForceClose的窗口。
2、记录打开的Activity:每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
3、发送特定广播:在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
4、递归退出在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。除了第一个,都是想办法把每一个Activity都结束掉,间接达到目的。但是这样做同样不完美。你会发现,如果自己的应用程序对每一个Activity都设置了nosensor,在两个Activity结束的间隙,sensor可能有效了。但至少,我们的目的达到了,而且没有影响用户使用。为了编程方便,最好定义一个Activity基类,处理这些共通问题。

7.android的service的生命周期?哪个方法可以多次被调用:

答:1)与采用Context.startService()方法启动服务有关的生命周期方法onCreate() -> onStart() -> onDestroy()onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。onDestroy()该方法在服务被终止时调用。

2)与采用Context.bindService()方法启动服务有关的生命周期方法onCreate() -> onBind() -> onUnbind() -> onDestroy()onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:onCreate() ->onStart() ->onBind() ->onUnbind()[重载后的方法需返回true] ->onRebind()

8.android的broadcast的生命周期:

答:1)Broadcast receiver生命周期中仅有一个回调方法:void onReceive(Context curContext, Intent broadcastMsg)当接收器接收到一条broadcast消息,Android就会调用onReceiver(),并传递给它一个Intent对象,这个对象携带着那条broadcast消息。我们认为仅当执行这个方式时,Broadcast receiver是活动的;这个方法返回时,它就终止了。这就是Broadcast receiver的生命周期。

2)由于Broadcast receiver的生命周期很短,一个带有活动的Broadcast receiver的进程是受保护的,以避免被干掉;但是别忘了有一点,Android会在任意时刻干掉那些携带不再活动的组件的进程,所以很可能会造成这个问题。

3)解决上述问题的方案采用一个Service来完成这项工作,Android会认为那个进程中(Service所在的进程)仍然有在活动的组件。

8.1.注册广播接收者两种方式的区别,及优缺点

答:首先写一个类要继承BroadcastReceiver

第一种:在清单文件中声明,添加

<receiveandroid:name=".IncomingSMSReceiver " >

<intent-filter>

<actionandroid:name="android.provider.Telephony.SMS_RECEIVED")

<intent-filter>

<receiver>

第二种使用代码进行注册如:

IntentFilterfilter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED");

IncomingSMSReceiverreceiver = new IncomgSMSReceiver();

registerReceiver(receiver.filter);

两种注册类型的区别是:

1)第一种是常驻型(静态注册),也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

2)第二种不是常驻型广播(动态注册),也就是说广播跟随程序的生命周期。

注册的方法有两种,一种是静态注册,一种是动态注册。

动态注册优点:在 Android 的广播机制中,动态注册的优先级是要高于静态注册优先级的,因此在必要的情况下,我们是需要动态注册广播接收器的。

静态注册优点:动态注册广播接收器还有一个特点,就是当用来注册的 Activity 关掉后,广播也就失效了。同时反映了静态注册的一个优势,就是无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器就是打开着的。

9.Activity 与 Task的启动模式有哪些,它们含义具体是什么?

答:在一个activity中,有多次调用startActivity来启动另一个activity,要想只生成一个activity实例,可以设置启动模式。

一个activity有四种启动模式:standed,signleTop,singleTask,singleInstance

Standed:标准模式,一调用startActivity()方法就会产生一个新的实例。

SingleTop:如果已经有一个实例位于activity栈顶,就不产生新的实例,而只是调用activity中的newInstance()方法。如果不位于栈顶,会产生一个新的实例。

singleTask:会在一个新的task中产生这个实例,以后每次调用都会使用这个,不会去产生新的实例了。

SingleInstance:这个和singleTask基本一样,只有一个区别:在这个模式下的activity实例所处的task中,只能有这个activity实例,不能有其他实例

10.android 中有哪几种解析xml的类?官方推荐哪种?以及它们的原理和区别:

答:XML解析主要有三种方式,SAX、DOM、PULL。常规在PC上开发我们使用Dom相对轻松些,但一些性能敏感的数据库或手机上还是主要采用SAX方 式,SAX读取是单向的,优点:不占内存空间、解析属性方便,但缺点就是对于套嵌多个分支来说处理不是很方便。而DOM方式会把整个XML文件加载到内存 中去,这里Android开发网提醒大家该方法在查找方面可以和XPath很好的结合如果数据量不是很大推荐使用,而PULL常常用在J2ME对于节点处 理比较好,类似SAX方式,同样很节省内存,在J2ME中我们经常使用的KXML库来解析。

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

答:可以将.db文件复制到Eclipse Android工程中的res raw目录中或者Assert目录中。

所有在res raw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将.db文件复制到res raw目录中

12.Android的五种数据存储方式:

答:sharedPreferences;文件;SQLite/contentProvider;网络

13.让Activity变成一个窗口:

答:Activity属性设定:有时候会做个应用程序是漂浮在手机主界面的。

这个只需要在设置下Activity的主题theme,即在Manifest.xml定义Activity的地方加一句:android :theme="@android:style/Theme.Dialog"如果是作半透明的效果:android:theme="@android:style/Theme.Translucent"

14.Android中常用的五种布局:

答:FrameLayout帧布局;RelativeLayout相对布局;LinearLayout线性布局;AbsoluteLayout绝对布局;TableLayout表格布局(逐渐淘汰,不推荐使用)

15.谈谈Android的IPC机制:

答:IPC是内部进程通信的简称,是共享"命名管道"的资源。Android中的IPC机制是为了让Activity和Service之间可以随时的进行交互,故在Android中该机制,只适用于Activity和Service之间的通信,类似于远程方法调用,类似于C/S模式的访问。通过定义AIDL接口文件来定义IPC接口。Servier端实现IPC接口,Client端调用IPC接口本地代理。

15.1.AIDL的全称是什么?如何工作?能处理哪些类型的数据?

答:AIDL(AndroidInterface Definition Language)android接口描述语言

16. 通过Intent传递一些二进制数据的方法有哪些? 1). 使用Serializable接口实现序列化,这是Java常用的方法。 2). 实现Parcelable接口,这里Android的部分类比如Bitmap类就已经实现了,同时Parcelable在Android AIDL中交换数据也很常见的。 17. 能说下Android应用的入口点吗? 真正的Android入口点是application的main,你可以看下androidmanifest.xml的包含关系就清楚了。 可以没有Activity但是必须有Application

18.Android系统中GC什么情况下会出现内存泄露呢?

出现情况:

1.数据库的cursor没有关闭

2.构造adapter时,没有使用缓存contentview , 衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程

3.Bitmap对象不使用时采用recycle()释放内存

4.activity中的对象的生命周期大于activity调试方法:DDMS==>HEAPSZIE==>dataobject==>[TotalSize]


邮箱:zz7zz7zz@163.com

微博:http://weibo.com/u/3209971935


更多相关文章

  1. Android(安卓)6.0 权限使用 以及小米手机权限的适配
  2. Android(安卓)不可缺少的异步(Thread、Handler、AsyncTask)实例解
  3. android ListView拖动时会黑屏的解决方法
  4. Android(安卓)通过源码解析 Fragment 启动过程
  5. 详解Android单元测试最佳实践
  6. 关于Android的线程问题
  7. 【Android解决方案】GridView第一次选中不调用onItemSelected()
  8. Android将应用程序指定默认语言
  9. Android(安卓)APK反编译方法(可以获取APK xml和android Manifest,j

随机推荐

  1. Android(安卓)相关
  2. Android的OpenGL学习笔记(1)
  3. android获取3G或wifi流量信息
  4. android中将中文以粗体显示
  5. TextView设置一行最多显示6个字是什么属
  6. Android(安卓)HandlerThread使用方法
  7. 完美解决android Studio打开报错 https:/
  8. Launcher
  9. Android(安卓)中Button点击频率的控制
  10. android提示错误: The process android.pr