android面试题

面试题 专栏收录该内容
3 篇文章 0 订阅
经过了一个多礼拜的准备自己的工作算是稳定下来,明天去报道,自己争取了一天休息的时间洗洗刷刷一些东西,断断续续的自己已经换了三份工作,这份工作打算静下心好好的做几年,今天外面下着大雨自己闲着无聊就把自己看过的和遇到的面试题整理下,都是一些常见的问题,如果看到相同的是我在网上和书上看来的答案希望大家不要在意是不是原创,自己是一个新手博客是记录下自己的收集方便以后的查找,自己写的都是基础没有什么干货,我想等以后自己能力上去了干货自己还是会写一些。

1丶android中常见的单位和尺寸?
   pt,px,dp,sp
pt是磅数的意思,一般都会作为字体的单位来使用。
px是像素的意思,屏幕中可以显示的最小元素单位。
pt,px一般用在pc上。
dp是密度无关的像素,也称作dip,和px相比它在不同密度的屏幕中的显示比例将保持一致。
sp是可伸缩像素,用于解决文字大小的适配问题。
dp,sp一般用在手机上,一个是距离,一个是大小。
2丶<include/>,<merge/>,<ViewStub/>的作用
include 布局重用
merge 减少视图层级
viewstub 在需要的时候添加
这三个是android布局优化的时候用到,当有人问android的优化措施有哪些
就把这三个回答在解释怎么用就行了,
-------添加----------------------------------------------------------------------
*  listview和recycleview 分别继承是
AbsListView和ViewGroup
*  android各个项目工程下各个目录的存放那些内容,例如assets目录的作用(较大的资源文件图片音乐字体等)。
*  属性动画要求动画作用的对象提供该属性的方法
get 和 set 方法
* 对象的引用四中级别从强到弱
强引用(StrongReference)
软引用(SoftReference)
弱引用(WeakReference)
虚引用(PhantomReference)
*  oninterceptTouchEvent 和onTouchEvent的作用
1、onInterceptTouchEvent()是用于处理事件(重点onInterceptTouchEvent这个事件是从父控件开始往子控件传的,直到有拦截或者到没有这个事件的view,然后就往回从子到父控件,这次是onTouch的
onTouchEvent()用于处理事件(重点onTouch这个事件是从子控件回传到父控件的,一层层向下传
* ArrayList HashMap ArrayMap的默认容量
答案:10  16  0
*  Acivity Window view三者之间的区别
ViewWindow以及 Activity主要是用于显示并与用户交互的
View组成成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
Window相当于一个容器,里面“盛放”着很多 View,这些 View是以树状结构组织起来的。
一个 Activity就“相当于”一个界面(通过 setContentView指定具体的 View)。我们可以直接在Activity里处理事件,如 onKeyEvent, onTouchEvent等。 并可以通过 Activity维护应用程序的生命周期。
*    图片加载的流程 这个自己百度吧,





-------------------------------------------------------------------------------------
3、 android 中的动画有哪几类,它们的特点和区别是什么

答:3种,一种是 Tween 动画(补间动画)、一种是 Frame 动画(逐帧动画)。以及Propert动画(属性动画)Tween 动画,这种 实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化,;另一种 Frame 动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影 Propert动画,这个是在Android 3.0中才引进的,它可以直接更改我们对象的属性。

4、 Android 的四大组件是哪些,它们的作用?

答: Activity:Activity 是 Android 程序与用户交互的窗口,是 Android 构造 块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥 善管理生命周期以及一些跳转逻辑 service:后台服务于 Activity,封装有一个完整的功能逻辑实现,接受上 层指令,完成相关的食物,定义好需要接受的 Intent 提供同步和异步的接 口 Content Provider:(内容提供器)是 Android 提供的第三方应用数据的访 问方案,可以派生 Content Provider 类,对外提供数据,可以像数据库一 样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的借口模型,大 大简化上层应用,对数据的整合提供了更方便的途径 BroadCast Receiver:接受一种或者多种 Intent 作触发事件,接受相关消 息,做一些简单处理,转换成一条 Notification,统一了 Android 的事件 广播模型


5、 请介绍下 Android 中常用的布局和形式。

分别是:FrameLayout(框架布局),LinearLayout (线 性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局), TableLayout(表格布局) 。

一、FrameLayout:所有东西依次都放在左上角,会重叠,这个布局比较简 单,也只能放一点比较简单的东西。

二、LinearLayout:线性布局,每一个 LinearLayout 里面又可分为垂直布 局(android:orientation="vertical")和水平布局 (android:orientation="horizontal" ) 。当垂直布局时,每一行就只有一 个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次 向右排列。

三、AbsoluteLayout:绝对布局用 X,Y 坐标来指定元素的位置, 这种布局方式也比较简单,但是在屏幕旋转时,往往会出问题,而且多个元 素的时候,计算比较麻烦。

四、RelativeLayout:相对布局可以理解为某一个元素为参照物,来定位的 布局方式。主要属性有:相对于某一个元素 android:layout_below、 android:layout_toLeftOf 相对于父元素的地方 android:layout_alignParentLeft、android:layout_alignParentRigh;

五、TableLayout:表格布局,每一个 TableLayout 里面有表格行 TableRow, TableRow 里面可以具体定义每一个元素。每一个布局都有自己 适合的方式, 这五个布局元素可以相互嵌套应用,做出美观的界面。


6、 ListView 的优化方案

答:1、如果自定义适配器,那么在 getView 方法中要考虑方法传进来的参 数 contentView 是否为 null,如果为 null 就创建 contentView 并返回,如果不 为 null 则直接使用。在这个方法中尽可能少创建 view。

2、给 contentView 设置 tag(setTag()),传入一个 viewHolder 对象,用 于缓存要显示的数据,可以达到图像数据异步加载的效果。

3、如果 listview 需要显示的 item 很多,就要考虑分页加载。比如一共要 显示 100 条或者更多的时候,我们可以考虑先加载 20 条,等用户拉到列表底部 的时候再去加载接下来的 20 条。


7、 请介绍下 Android 的数据存储方式。

答:使用 SharedPreferences 存储数据;文件存储数据;SQLite 数据库存储 数据;使用 ContentProvider 存储数据;网络存储数据; Preference,File, DataBase 这三种方式分别对应的目录是 /data/data/Package Name/Shared_Pref, /data/data/Package Name/files, /data/data/Package Name/database 。

一:使用 SharedPreferences 存储数据 首先说明 SharedPreferences 存储方式,它是 Android 提供的用来存储一些 简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了 Map 数据 结构来存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下: void ReadSharedPreferences(){ String strName,strPassword; SharedPreferences user = getSharedPreferences(“user_info”,0); strName = user.getString(“NAME”,””); strPassword = user getString(“PASSWORD”,””); } void WriteSharedPreferences(String strName,String strPassword){ SharedPreferences user = getSharedPreferences(“user_info”,0); uer.edit(); user.putString(“NAME”, strName); user.putString(“PASSWORD” ,strPassword); user.commit(); } 数据读取与写入的方法都非常简单,只是在写入的时候有些区别:先调用
edit()使其处于编辑状态,然后才能修改数据,最后使用 commit()提交修改的 数据。实际上 SharedPreferences 是采用了 XML 格式将数据存储到设备中,在 DDMS 中的 File Explorer 中的/data/data/<package name>/shares_prefs 下。 使用 SharedPreferences 是有些限制的:只能在同一个包内使用,不能在不同的 包之间使用。

二:文件存储数据 文件存储方式是一种较常用的方法,在 Android 中读取/写入文件的方法, 与 Java 中实现 I/O 的程序是完全一样的,提供了 openFileInput()和 openFileOutput()方法来读取设备上的文件。具体实例如下: String fn = “moandroid.log”; FileInputStream fis = openFileInput(fn); FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);

三:网络存储数据 网络存储方式,需要与 Android 网络数据包打交道,关于 Android 网络数 据包的详细说明,请阅读 Android SDK 引用了 Java SDK 的哪些 package?。 四:ContentProvider 1、ContentProvider 简介 当应用继承 ContentProvider 类,并重写该类用于提供数据和存储数据的方 法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但 数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需 要进行文件操作读写数据;采用 sharedpreferences 共享数据,需要使用 sharedpreferences API 读写数据。而使用 ContentProvider 共享数据的好处是 统一了数据访问方式。 2、Uri 类简介 Uri 代表了要操作的数据,Uri 主要包含了两部分信息:1.需要操作的 ContentProvider ,2.对 ContentProvider 中的什么数据进行操作,一个 Uri 由以下几部分组成: 1.scheme:ContentProvider(内容提供者)的 scheme 已经由 Android 所规 定为:content://… 2.主机名(或 Authority):用于唯一标识这个 ContentProvider,外部调用 者可以根据这个标识来找到它。 3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务 而定,如下: 要操作 contact 表中 id 为 10 的记录,可以构建这样的路径:/contact/10 要操作 contact 表中 id 为 10 的记录的 name 字段, contact/10/name 要操作 contact 表中的所有记录,可以构建这样的路径:/contact? 要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下: 要操作 xml 文件中 contact 节点下的 name 节点,可以构建这样的路径: /contact/name 如果要把一个字符串转换成 Uri,可以使用 Uri 类中的 parse()方法,如下: Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact" ) 3、UriMatcher、ContentUrist 和 ContentResolver 简介
因为 Uri 代表了要操作的数据,所以我们很经常需要解析 Uri,并从 Uri 中 获取数据。Android 系统提供了两个用于操作 Uri 的工具类,分别为 UriMatcher 和 ContentUris 。掌握它们的使用,会便于我们的开发工作。 UriMatcher:用于匹配 Uri,它的用法如下:
1.首先把你需要匹配 Uri 路径全部给注册上,如下: //常量 UriMatcher.NO_MATCH 表示不匹配任何路径的返回码(-1)。 UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //如果 match()方法匹配 content://com.changcheng.sqlite.provider.contactprovider /contact 路 径,返回匹配码为 1 uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider ”, “contact”, 1);//添加需要匹配 uri,如果匹配就会返回匹配码 //如果 match()方法匹配 content://com.changcheng.sqlite.provider.contactprovider/contact/230 路径,返回匹配码为 2 uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider ”, “contact/#”, 2);//#号为通配符 2.注册完需要匹配的 Uri 后,就可以使用 uriMatcher.match(uri)方法对输 入的 Uri 进行匹配,如果匹配就返回匹配码,匹配码是调用 addURI()方法传入 的第三个参数,假设匹配 content://com.changcheng.sqlite.provider.contactprovider/contact 路 径,返回的匹配码为 1。 ContentUris:用于获取 Uri 路径后面的 ID 部分,它有两个比较实用的方法: withAppendedId(uri, id)用于为路径加上 ID 部分 parseId(uri)方法用于从路径中获取 ID 部分 ContentResolver:当外部应用需要对 ContentProvider 中的数据进行添加、 删除、修改和查询操作时,可以使用 ContentResolver 类来完成,要获取 ContentResolver 对象,可以使用 Activity提供的 getContentResolver()方法。 ContentResolver 使用 insert、delete、update、query 方法,来操作数据。


8、 activity 的启动模式有哪些?是什么含义?

答:在 android 里,有 4 种 activity 的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance”
它们主要有如下不同: 1. 如何决定所属 task “standard”和”singleTop”的 activity 的目标 task,和收到的 Intent 的发送者在同一个 task 内,除非 intent 包括参数 FLAG_ACTIVITY_NEW_TASK。 如果提供了 FLAG_ACTIVITY_NEW_TASK 参数,会启动到别的 task 里。 “singleTask”和”singleInstance”总是把 activity 作为一个 task 的根
元素,他们不会被启动到一个其他 task 里。

2. 是否允许多个实例 “standard”和”singleTop”可以被实例化多次,并且存在于不同的 task 中,且一个 task 可以包括一个 activity 的多个实例; “singleTask”和”singleInstance”则限制只生成一个实例,并且是 task 的根元素。 singleTop 要求如果创建 intent 的时候栈顶已经有要创建 的 Activity 的实例,则将 intent 发送给该实例,而不发送给新的实例。

3. 是否允许其它 activity 存在于本 task 内 “singleInstance”独占一个 task,其它 activity 不能存在那个 task 里; 如果它启动了一个新的 activity,不管新的 activity 的 launch mode 如何,新 的 activity 都将会到别的 task 里运行(如同加了 FLAG_ACTIVITY_NEW_TASK 参 数)。 而另外三种模式,则可以和其它 activity 共存。

4. 是否每次都生成新实例 “standard”对于没一个启动 Intent 都会生成一个 activity 的新实例; “singleTop”的 activity 如果在 task 的栈顶的话,则不生成新的该 activity 的实例,直接使用栈顶的实例,否则,生成该 activity 的实例。 比如现在 task栈元素为 A-B-C-D (D 在栈顶) ,这时候给 D发一个启动 intent, 如果 D 是 “standard”的,则生成 D 的一个新实例,栈变为 A-B-C-D-D。 如果 D 是 singleTop 的话,则不会生产 D 的新实例,栈状态仍为 A-B-C-D 如果这时候给 B 发 Intent 的话,不管 B 的 launchmode 是”standard” 还 是 “singleTop” ,都会生成 B 的新实例,栈状态变为 A-B-C-D-B。 “singleInstance”是其所在栈的唯一 activity,它会每次都被重用。 “singleTask”如果在栈顶,则接受 intent,否则,该 intent 会被丢弃, 但是该 task 仍会回到前台。 当已经存在的 activity 实例处理新的 intent 时候,会调用 onNewIntent() 方法 如果收到 intent 生成一个 activity 实例,那么用户可以通过 back 键回到 上一个状态;如果是已经存在的一个 activity 来处理这个 intent 的话,用户不 能通过按 back 键返回到这之前的状态。

9、 请描述下 Activity 的生命周期。

答:activity 的生命周期方法有:onCreate()、onStart()、onReStart()、 onResume()、onPause()、onStop()、onDestory(); 可见生命周期:从 onStart()直到系统调用 onStop() 前台生命周期:从 onResume()直到系统调用 onPause()


10、 activity在屏幕旋转时的生命周期

答:不设置 Activity 的 android:configChanges 时,切屏会重新调用各个 生命周期,切横屏时会执行一次,切竖屏时会执行两次;设置 Activity 的 android:configChanges="orientation"时,切屏还是会重新调用各个生命 周期,切横、竖屏时只会执行一次;设置 Activity 的 android:configChanges="orientation|keyboardHidden"时,切屏不会重新 调用各个生命周期,只会执行 onConfigurationChanged 方法

11、 如何启用 Service,如何停用 Service。

服务的开发比较简单,如下:

第一步:继承 Service 类 public class SMSService extends Service {}

第二步:在 AndroidManifest.xml 文件中的<application>节点里对服务进 行配置:<service android:name=".SMSService" /> 服务不能自己运行,需要通过调用 Context.startService()或 Context.bindService()方法启动服务。这两个方法都可以启动 Service,但是 它们的使用场合有所不同。使用 startService()方法启用服务,调用者与服务 之间没有关连,即使调用者退出了,服务仍然运行。使用 bindService()方法启 用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不 求同时生,必须同时死”的特点。 如果打算采用 Context.startService()方法启动服务,在服务未被创建 时,系统会先调用服务的 onCreate()方法,接着调用 onStart()方法。如果调用 startService()方法前服务已经被创建,多次调用 startService()方法并不会 导致多次创建服务,但会导致多次调用 onStart()方法。采用 startService() 方法启动的服务,只能调用 Context.stopService()方法结束服务,服务结束时 会调用 onDestroy()方法。 如果打算采用 Context.bindService()方法启动服务,在服务未被创建 时,系统会先调用服务的 onCreate()方法,接着调用 onBind()方法。这个时候
调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的 onUnbind() 方法,接着调用 onDestroy()方法。如果调用 bindService()方法前服务已经被 绑定,多次调用 bindService()方法并不会导致多次创建服务及绑定(也就是说 onCreate()和 onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的 服务解除绑定,可以调用 unbindService()方法,调用该方法也会导致系统调用 服务的 onUnbind()-->onDestroy()方法。
服务常用生命周期回调方法如下: onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调 用多少次 startService()或 bindService()方法,服务也只被创建一次。 onDestroy()该方法在服务被终止时调用。 与采用 Context.startService()方法启动服务有关的生命周期方法 onStart() 只有采用 Context.startService()方法启动服务时才会回调该 方法。该方法在服务开始运行时被调用。多次调用 startService()方法尽管不 会多次创建服务,但 onStart() 方法会被多次调用。 与采用 Context.bindService()方法启动服务有关的生命周期方法 onBind()只有采用 Context.bindService()方法启动服务时才会回调该方 法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用 Context.bindService()方法并不会导致该方法被多次调用。 onUnbind()只有采用 Context.bindService()方法启动服务时才会回调该方 法。该方法在调用者与服务解除绑定时被调用


12、 注册广播有几种方式,这些方式有何优缺点?请谈谈 Android 引入广播 机制的用意。

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

第一种:在清单文件中声明,添加 <receive android:name=".IncomingSMSReceiver " > <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED") <intent-filter> <receiver>

第二种使用代码进行注册如: IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); IncomingSMSReceiver receiver = new IncomgSMSReceiver(); registerReceiver(receiver.filter); 两种注册类型的区别是: 1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。 2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也 会被系统调用自动运行。


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

答:简单的说,Handler 获取当前线程中的 looper 对象,looper 用来从存 放 Message 的 MessageQueue 中取出 Message,再有 Handler 进行 Message 的分 发和处理. Message Queue(消息队列):用来存放通过 Handler 发布的消息,通常附属 于某一个创建它的线程,可以通过 Looper.myQueue()得到当前线程的消息队列 Handler:可以发布或者处理一个消息或者操作一个 Runnable,通过 Handler 发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中 的消息 Looper:是 Handler 和消息队列之间通讯桥梁,程序组件首先通过 Handler 把消息传递给 Looper,Looper 把消息放入队列。Looper 也把消息队列里的消息 广播给所有的 Handler:Handler 接受到消息后调用 handleMessage 进行处理 Message:消息的类型,在 Handler 类中的 handleMessage 方法中得到单个 的消息进行处理 在单线程模型下,为了线程通信问题,Android 设计了一个 Message Queue(消息队列),线程间可以通过该 Message Queue 并结合 Handler 和 Looper 组件进行信息交换。下面将对它们进行分别介绍: 1. Message Message 消息,理解为线程间交流的信息,处理数据后台线程需要更新 UI,则发送 Message 内含一些数据给 UI 线程。 2. Handler Handler 处理者,是 Message 的主要处理者,负责 Message 的发送, Message 内容的执行处理。后台线程就是通过传进来的 Handler 对象引用来 sendMessage(Message)。而使用 Handler,需要 implement 该类的 handleMessage(Message)方法,它是处理这些 Message 的操作内容,例如 Update UI。通常需要子类化 Handler 来实现 handleMessage 方法。 3. Message Queue Message Queue 消息队列,用来存放通过 Handler 发布的消息,按照先 进先出执行。 每个 message queue 都会有一个对应的 Handler。Handler 会向 message queue 通过两种方法发送消息:sendMessage 或 post。这两种消息都会插在 message queue 队尾并按先进先出执行。但通过这两种方法发送的消息执行的方 式略有不同:通过 sendMessage 发送的是一个 message 对象,会被 Handler 的 handleMessage()函数处理;而通过 post 方法发送的是一个 runnable 对象,则 会自己执行。 4. Looper Looper 是每条线程里的 Message Queue 的管家。Android 没有 Global 的 Message Queue,而 Android 会自动替主线程(UI 线程)建立 Message Queue, 但在子线程里并没有建立 Message Queue。所以调用 Looper.getMainLooper() 得到的主线程的 Looper 不为 NULL,但调用 Looper.myLooper() 得到当前线程的 Looper 就有可能为 NULL。对于子线程使用 Looper,API Doc 提供了正确的使用 方法:这个 Message 机制的大概流程:
1. 在 Looper.loop()方法运行开始后,循环地按照接收顺序取出 Message Queue 里面的非 NULL 的 Message。 2. 一开始 Message Queue 里面的 Message 都是 NULL 的。当 Handler.sendMessage(Message)到 Message Queue,该函数里面设置了那个 Message 对象的 target 属性是当前的 Handler 对象。随后 Looper 取出了那个 Message,则调用 该 Message 的 target 指向的 Hander 的 dispatchMessage 函数 对 Message 进行处理。在 dispatchMessage 方法里,如何处理 Message 则由用户 指定,三个判断,优先级从高到低: 1) Message 里面的 Callback,一个实现了 Runnable 接口的对象,其中 run 函数做处理工作; 2) Handler 里面的 mCallback 指向的一个实现了 Callback 接口的对象, 由其 handleMessage 进行处理; 3) 处理消息 Handler 对象对应的类继承并实现了其中 handleMessage 函数,通过这个实现的 handleMessage 函数处理消息。 由此可见,我们实现的 handleMessage 方法是优先级最低的! 3. Handler处理完该Message (update UI) 后,Looper则设置该Message 为 NULL,以便回收! 在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终 谁来执行处理信息之类的,个人理解是最简单的方法——判断 Handler 对象里面 的 Looper 对象是属于哪条线程的,则由该线程来执行! 1. 当 Handler 对象的构造函数的参数为空,则为当前所在线程的 Looper; 2. Looper.getMainLooper()得到的是主线程的 Looper 对象, Looper.myLooper()得到的是当前线程的 Looper 对象。


14、 简要解释一下activity、intent 、intent filter、service、Broadcase、 BroadcaseReceiver

答:一个 activity 呈现了一个用户可以操作的可视化用户界面;一个 service 不包含可见的用户界面,而是在后台运行,可以与一个 activity 绑定, 通过绑定暴露出来接口并与其进行通信;一个 broadcast receiver 是一个接收 广播消息并做出回应的 component,broadcast receiver 没有界面;一个 intent 是一个 Intent 对象,它保存了消息的内容。对于 activity 和 service 来说,它 指定了请求的操作名称和待操作数据的 URI,Intent 对象可以显式的指定一个目 标 component。如果这样的话,android 会找到这个 component(基于 manifest 文件中的声明)并激活它。但如果一个目标不是显式指定的,android 必须找到 响应 intent 的最佳 component。它是通过将 Intent 对象和目标的 intent filter 相比较来完成这一工作的;一个 component 的 intent filter 告诉 android 该 component 能处理的 intent。intent filter 也是在 manifest 文件中声明的。


15、 说说 mvc 模式的原理,它在 android 中的运用,android的官方建议应用 程序的开发采用 mvc 模式。何谓 mvc? mvc 是 model,view,controller 的缩写,mvc 包含三个部分: 模型(model)对象:是应用程序的主体部分,所有的业务逻辑都应该 写在该层。
视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整 个 mvc
架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。 控制器(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 里面处理,当然对业务计算等操作也是必须放在的该层的。


16、 什么是 ANR 如何避免它?

答:ANR:Application Not Responding。在 Android 中,活动管理器和窗 口管理器这两个系统服务负责监视应用程序的响应,当用户操作的在 5s 内应用 程序没能做出反应,BroadcastReceiver 在 10 秒内没有执行完毕,就会出现应 用程序无响应对话框,这既是 ANR。 避免方法:Activity 应该在它的关键生命周期方法(如 onCreate()和 onResume())里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库 操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者异步方式)来 完成。主线程应该为子线程提供一个 Handler,以便完成时能够提交给主线程。


17、 什么情况会导致 Force Close ?如何避免?能否捕获导致其的异常?

答:程序出现异常,比如 nullpointer。 避免:编写程序时逻辑连贯,思维缜密。能捕获异常,在 logcat 中能看到 异常信息


18、 描述一下 android 的系统架构

android 系统架构分从下往上为 linux 内核层、运行库、应用程序框架层、 和应用程序层。 linuxkernel:负责硬件的驱动程序、网络、电源、系统安全以及内存管理 等功能。 libraries 和 android runtime:libraries:即 c/c++函数库部分,大多数 都是开放源代码的函数库,例如 webkit(引擎),该函数库负责 android 网页浏 览器的运行,例如标准的 c 函数库 libc、openssl、sqlite 等,当然也包括支持 游戏开发 2dsgl 和 3dopengles,在多媒体方面有 mediaframework 框架来支持各 种影音和图形文件的播放与显示,例如 mpeg4、h.264、mp3、 aac、amr、jpg 和 png 等众多的多媒体文件格式。android 的 runtime 负责解释和执行生成的
dalvik 格式的字节码。 applicationframework(应用软件架构),java 应用程序开发人员主要是使 用该层封装好的 api 进行快速开发。 applications:该层是 java 的应用程序层,android 内置的 googlemaps、 e-mail、即时通信工具、浏览器、mp3 播放器等处于该层,java 开发人员开发的 程序也处于该层,而且和内置的应用程序具有平等的位置,可以调用内置的应用 程序,也可以替换内置的应用程序。 上面的四个层次,下层为上层服务,上层需要下层的支持,调用下层的服务, 这种严格分层的方式带来的极大的稳定性、灵活性和可扩展性,使得不同层的开 发人员可以按照规范专心特定层的开发。 android 应用程序使用框架的 api 并在框架下运行,这就带来了程序开发的 高度一致性,另一方面也告诉我们,要想写出优质高效的程序就必须对整个 applicationframework 进行非常深入的理解。精通 applicationframework,你 就可以真正的理解 android 的设计和运行机制,也就更能够驾驭整个应用层的开 发。


19、 请介绍下 ContentProvider 是如何实现数据共享的。

一个程序可以通过实现一个 Content provider 的抽象接口将自己的数据完 全暴露出去,而且 Content providers 是以类似数据库中表的方式将数据暴露。 Content providers 存储和检索数据,通过它可以让所有的应用程序访问到,这 也是应用程序之间唯一共享数据的方法。 要想使应用程序的数据公开化,可通过 2 种方法:创建一个属于你自己的 Content provider或者将你的数据添加到一个已经存在的 Content provider 中, 前提是有相同数据类型并且有写入 Content provider 的权限。 如何通过一套标准及统一的接口获取其他应用程序暴露的数据? Android 提供了 ContentResolver,外界的程序可以通过 ContentResolver 接口访问 ContentProvider 提供的数据。


20、 Android 本身的 api 并未声明会抛出异常,则其在运行时有无可能抛出 runtime 异常,你遇到过吗?诺有的话会导致什么问题?如何解决?

答:会,比如 nullpointerException。我遇到过,比如 textview.setText() 时,textview 没有初始化。会导致程序无法正常运行出现 forceclose。打开控 制台查看 logcat 信息找出异常信息并修改程序。


21、 IntentService有何优点?

答:Acitivity 的进程,当处理 Intent 的时候,会产生一个对应的 Service; Android 的进程处理器现在会尽可能的不 kill 掉你;非常容易使用


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

答:重写 onSaveInstanceState()方法,在此方法中保存需要保存的数据, 该方法将会在 activity 被回收之前调用。通过重写 onRestoreInstanceState() 方法可以从中提取保存好的数据


23、 如何将一个 Activity 设置成窗口的样式。

答:<activity>中配置: android :theme="@android:style/Theme.Dialog" 另外 android:theme="@android:style/Theme.Translucent" 是设置透明


24、 如何退出 Activity?如何安全退出已调用多个 Activity 的 Application?

答:对于单一 Activity 的应用来说,退出很简单,直接 finish()即可。当然, 也可以用 killProcess()和 System.exit()这样的方法。 对于多个 activity,1、记录打开的 Activity:每打开一个 Activity,就记录下 来。在需要退出时,关闭每一个 Activity 即可。2、发送特定广播:在需要结束 应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭即可。3、递归 退出:在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在 onActivityResult 中处理,递归关闭。为了编程方便,最好定义一个 Activity 基类, 处理这些共通问题。
在 2.1 之前,可以使用 ActivityManager 的 restartPackage 方法。 它可以直接结束整个应用。在使用时需要权限 android.permission.RESTART_PACKAGES。 注意不要被它的名字迷惑。 可是,在 2.2,这个方法失效了。在 2.2 添加了一个新的方法,killBackground Processes(),需要权限 android.permission.KILL_BACKGROUND_PROCESSES。可 惜的是,它和 2.2 的 restartPackage 一样,根本起不到应有的效果。 另外还有一个方法,就是系统自带的应用程序管理里,强制结束程序的方法, forceStopPackage()。它需要权限 android.permission.FORCE_STOP_PACKAGES。 并且需要添加 android:sharedUserId="android.uid.system"属性。同样可惜的 是,该方法是非公开的,他只能运行在系统进程,第三方程序无法调用。 因为需要在 Android.mk 中添加 LOCAL_CERTIFICATE := platform。 而 Android.mk 是用于在 Android 源码下编译程序用的。 从以上可以看出,在 2.2,没有办法直接结束一个应用,而只能用自己的办法间 接办到。 现提供几个方法,供参考: 1、抛异常强制退出: 该方法通过抛异常,使程序 Force Close。 验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出 Force Close 的窗口。 2、记录打开的 Activity: 每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。 3、发送特定广播: 在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关 闭即可。 4、递归退出 在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,
在 onActivityResult 中处理,递归关闭。 除了第一个,都是想办法把每一个 Activity 都结束掉,间接达到目的。但 是这样做同样不完美。你会发现,如果自己的应用程序对每一个 Activity 都设 置了 nosensor,在两个 Activity 结束的间隙,sensor 可能有效了。但至少,我 们的目的达到了,而且没有影响用户使用。为了编程方便,最好定义一个 Activity 基类,处理这些共通问题。


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

答:全称是:Android Interface Define Language 在 Android 中, 每个应用程序都可以有自己的进程. 在写 UI 应用的时候, 经常要用到 Service. 在不同的进程中, 怎样传递对象呢?显然, Java 中不允许 跨进程内存共享. 因此传递对象, 只能把对象拆分成操作系统能理解的简单形 式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化 传递对象. 在 Android 中, 则采用 AIDL 的方式. 理论上 AIDL 可以传递 Bundle, 实际上做起来却比较麻烦。 AIDL(AndRoid 接口描述语言)是一种借口描述语言; 编译器可以通过 aidl 文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如 果需要在一个 Activity 中, 访问另一个 Service 中的某个对象, 需要先将对象 转化成 AIDL 可识别的参数(可能是多个参数), 然后使用 AIDL 来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象. AIDL 的 IPC 的机制和 COM 或 CORBA 类似, 是基于接口的,但它是轻量级的。它 使用代理类在客户端和实现层间传递值. 如果要使用 AIDL, 需要完成 2 件事情: 1. 引入 AIDL 的相关类.; 2. 调用 aidl 产生的 class. AIDL 的创建方法: AIDL 语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数 和返回值。由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些 AIDL 支持的数据类型: 1. 不需要 import 声明的简单 Java 编程语言类型(int,boolean 等) 2. String, CharSequence 不需要特殊声明 3. List, Map 和 Parcelables 类型, 这些类型内所包含的数据成员也只能是 简单数据类型, String 等其他比支持的类型. (另外: 我没尝试 Parcelables, 在 Eclipse+ADT 下编译不过, 或许以后会有所 支持)


26、 请解释下 Android 程序运行时权限与文件系统权限的区别。

答:运行时权限 Dalvik( android 授权) 文件系统 linux 内核授权


27、 系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原 由。

通过直接发送 Uri 把参数带过去,或者通过 manifest 里的 intentfilter 里 的 data 属性


28、 android 系统的优势和不足

答:Android 平台手机 5 大优势: 一、开放性 在优势方面,Android 平台首先就是其开发性,开发的平台允许任何移动终 端厂商加入到 Android 联盟中来。显著的开放性可以使其拥有更多的开发者,随 着用户和应用的日益丰富,一个崭新的平台也将很快走向成熟。开放性对于 Android 的发展而言,有利于积累人气,这里的人气包括消费者和厂商,而对于 消费者来讲,随大的受益正是丰富的软件资源。开放的平台也会带来更大竞争, 如此一来,消费者将可以用更低的价位购得心仪的手机。 二、挣脱运营商的束缚 在过去很长的一段时间,特别是在欧美地区,手机应用往往受到运营商制约, 使用什么功能接入什么网络,几乎都受到运营商的控制。从去年 iPhone 上市 , 用户可以更加方便地连接网络,运营商的制约减少。随着 EDGE、HSDPA 这些 2G 至 3G 移动网络的逐步过渡和提升,手机随意接入网络已不是运营商口中的笑谈, 当你可以通过手机 IM 软件方便地进行即时聊天时,再回想不久前天价的彩信和 图铃下载业务,是不是像噩梦一样?互联网巨头 Google 推动的 Android 终端天 生就有网络特色,将让用户离互联网更近。 三、丰富的硬件选择 这一点还是与 Android 平台的开放性相关,由于 Android 的开放性,众多的 厂商会推出千奇百怪,功能特色各具的多种产品。功能上的差异和特色,却不会 影响到数据同步、甚至软件的兼容,好比你从诺基亚 Symbian 风格手机 一下改 用苹果 iPhone ,同时还可将 Symbian 中优秀的软件带到 iPhone 上使用、联系 人等资料更是可以方便地转移,是不是非常方便呢? 四、不受任何限制的开发商 Android 平台提供给第三方开发商一个十分宽泛、自由的环境,不会受到各 种条条框框的阻扰,可想而知,会有多少新颖别致的软件会诞生。但也有其两面 性,血腥、暴力、情色方面的程序和游戏如可控制正是留给 Android 难题之一。 五、无缝结合的 Google 应用 如今叱诧互联网的 Google 已经走过 10 年度历史,从搜索巨人到全面的互联 网渗透,Google 服务如地图、邮件、搜索等已经成为连接用户和互联网的重要 纽带,而 Android 平台手机将无缝结合这些优秀的 Google 服务。 再说 Android 的 5 大不足: 一、安全和隐私 由于手机 与互联网的紧密联系,个人隐私很难得到保守。除了上网过程中 经意或不经意留下的个人足迹,Google 这个巨人也时时站在你的身后,洞穿一 切,因此,互联网的深入将会带来新一轮的隐私危机。 二、首先开卖 Android 手机的不是最大运营商 众所周知,T-Mobile 在 23 日,于美国纽约发布 了 Android 首款手机 G1。 但是在北美市场,最大的两家运营商乃AT&T和Verizon,而目前所知取得Android 手机销售权的仅有 T-Mobile 和 Sprint,其中 T-Mobile 的 3G 网络相对于其他三 家也要逊色不少,因此,用户可以买账购买 G1,能否体验到最佳的 3G 网络服务 则要另当别论了! 三、运营商仍然能够影响到 Android 手机 在国内市场,不少用户对购得移动定制机不满,感觉所购的手机被人涂画了
广告一般。这样的情况在国外市场同样出现。Android 手机的另一发售运营商 Sprint 就将在其机型中内置其手机商店程序。 四、同类机型用户减少 在不少手机论坛都会有针对某一型号的子论坛,对一款手机的使用心得交 流,并分享软件资源。而对于 Android 平台手机,由于厂商丰富,产品类型多样, 这样使用同一款机型的用户越来越少,缺少统一机型的程序强化。举个稍显不当 的例子,现在山寨机泛滥,品种各异,就很少有专门针对某个型号山寨机的讨论 和群组,除了哪些功能异常抢眼、颇受追捧的机型以外。 五、过分依赖开发商缺少标准配置 在使用 PC 端的 Windows Xp 系统的时候,都会内置微软 Windows Media Player 这样一个浏览器程序,用户可以选择更多样的播放器,如 Realplay 或暴风影音 等。但入手开始使用默认的程序同样可以应付多样的需要。在 Android 平台中, 由于其开放性,软件更多依赖第三方厂商,比如 Android 系统的 SDK 中就没有内 置音乐 播放器,全部依赖第三方开发,缺少了产品的统一性。


29、 Android dvm 的进程和 Linux 的进程, 应用程序的进程是否为同一个概 念

答:DVM 指 dalivk 的虚拟机。每一个 Android 应用程序都在它自己的进程中 运行,都拥有一个独立的 Dalvik 虚拟机实例。而每一个 DVM 都是在 Linux 中的 一个进程,所以说可以认为是同一个概念。


30、 sim 卡的 EF 文件是什么?有何作用

答:sim 卡的文件系统有自己规范,主要是为了和手机通讯,sim 本 身可以 有自己的操作系统,EF 就是作存储并和手机通讯用的


31、 嵌入式操作系统内存管理有哪几种,

各有何特性 页式,段式,段页,用到了 MMU,虚拟空间等技术


32、 什么是嵌入式实时操作系统, Android 操作系统属于实时操作系统吗?

嵌入式实时操作系统是指当外界事件或数据产生时,能够接受并以足够快 的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理 系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。主要 用于工业控制、 军事设备、 航空航天等领域对系统的响应时间有苛刻的要求, 这就需要使用实时系统。又可分为软实时和硬实时两种,而 android是基于 linux 内核的,因此属于软实时。


33、 一条最长的短信息约占多少 byte?

中文 70(包括标点),英文 160,160 个字节。


34、 有一个一维整型数组 int[]data 保存的是一张宽为 width,高为 height 的图片像素值信息。请写一个算法,将该图片所有的白色不透明 (0xffffffff)像素点的透明度调整为 50%。


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

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


36、 如何将打开 res/raw 目录中的数据库文件?

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


37、 DDMS 和 TraceView的区别?

DDMS 是一个程序执行查看器,在里面可以看见线程和堆栈等信息,TraceView 是程序性能分析器 。


38、 java 中如何引用本地语言 可以用 JNI(java native interface java 本地接口)接口 。


39、 谈谈 Android 的 IPC(进程间通信)机制 IPC 是内部进程通信的简称, 是共享"命名管道"的资源。

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


40、 NDK 是什么

NDK 是一些列工具的集合,NDK 提供了一系列的工具,帮助开发者迅速的开 发 C/C++的动态库,并能自动将 so 和 java 应用打成 apk 包。 NDK 集成了交叉编译器,并提供了相应的 mk 文件和隔离 cpu、平台等的差异,开 发人员只需简单的修改 mk 文件就可以创建出


还有一些问题,就是你使用过的第三方开源库及他们的优点,常见的设计模式,android6.0系统中那些权限需要动态申请权限,横竖屏切换时候的生命周期,oom的的情况和处理,mvc模式的好处,这些大家自己查吧,差不多了自己要去吃饭。








  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值