1.常用的存储方式有哪些?
(五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持读取不支持写入,写入引用Editor。
SQLite:
SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。
SharedPreference:
除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置。
File:
即常说的文件(I/O)存储方法,常用语存储大数量的数据,但是缺点是更新数据将是一件困难的事情。
ContentProvider:
Android 系统中能实现所有应用程序共享的一种数据存储方式,由于数据通常在各应用间的是互相私密的,所以此存储方式较少使用,但是其又是必不可少的一种存储方式。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个ContentProvider都会对外提供一个公共的URI(包装成Uri对 象),如果应用程序有数据需要共享时,就需要使用ContentProvider为这些数据定义一个URI,然后其他的应用程序就通过 Content Provider传入这个URI来对数据进行操作。
网络存储:
从网络读取数据和写入数据。 Android提供了通过网络来实现数据的存储和获取的方法。
我们可以调用WebService返回的数据或是解析HTTP协议实现网络数据交互。
2.安卓中动画有几类,他们的特点和区别?(
在国内的很多网站上动画都分为两种:帧动画和补间动画,但是在安卓的官网上在3.0,又加入一种属性动画.也就是现在有3种动画.
1: Property Animation(属性动画别加入在3.0)
2: View Animation (补间动画分为:透明,旋转,位移,缩放)
注意:补间动画是假动画,比如一个位移从A移动到B,如果给他设置监听事件,他的点击区域永远都在A,但是属性动画,如果给他设置点击事件,同样从A移动到B,他的点击区域就在B.
3: Drawable Animation(帧动画帧动画类似于放电影,通过播放已经排列放好的图片来实现。)
两种,一种是补间动画,还有一种是帧动画,帧动画类似于放电影,通过播放已经排列放好的图片来实现。
补间动画的实现定义开始和结束,中间由系统计算得出效果有透明,位移,放大缩小等等。
自定义录音或者进度条过程,会应用到帧动画,补间动画,一般用于应用的欢迎界面。
(菜单弹出,例如赞和评论,是个动画过程。)
3.handler机制原理
在安卓中有4大组件:activity,service,contentprovider,broadcastreceiver,这4大组件都运行在主线,谷歌官方规定,安卓不能再主线程做耗时操作,负责会造成ANR,为了避免这种情况的出现,必须开线程处理耗时操作,但是安卓规定,子线程不能更新UI,所以安卓引入了Handler机制,
(因为安卓中的UI控件不是线程安全的,如果在多线程中,并发访问可能会导致UI控件处于不可预期的状态,(为啥系统不对UI控件的访问加锁机制,缺点有两个1:加上锁机制会让UI访问的逻辑变的复杂,其次锁机制会降低UI访问的效率,因为锁机制会阻塞某些线程的执行,最简单最高效就是采用单线程来处理,对于我们来说也不是很麻烦,只需要通过Handler切换一下UI访问的执行线程即可))
Handler主要用于线程间的通信。
一个Handler允许发送和处理Message和Runable对象,UI主线程会自动分配一个Looper(消息轮询器),每个Looper中封装着MessageQueue(消息队列),遵循先进先出原则。Looper负责不断的从自己的消息队列里取出队头的任务或消息执行。一般是在子线程执行完耗时操作之后,通过Handler的sendMessage或post方法将Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们(用到handleMessage方法,主要执行刷新UI的代码)。
其中Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域。
4除了handler和子线程,还有一个处理线程的是什么,主要方法是什么?
AsynTask,doInbackGround+onPostExecute
doInBackground() 这个方法运行在后台线程中,主要负责执行那些很耗时的操作,如访问网络。该方法必须重写。
onPostExecute(Result) 这个方法运行于UI主线程,在doInBackground(Params…)方法执行后调用,该方法用于接收后台任务执行后返回的结果,刷新UI显示
5.tcp和udp区别.
TCP---(长链接)(管发管收,数据安全)传输控制协议,提供的是面向连接、可靠的字节流服务,传输数据前经过“三次握手”建立连接,保证数据传输的可靠性,但效率比较低。一般用于对于数据传输安全性较高的场合。
UDP---(短连接,只管发,不管收,想聊天就是UDK,丢了几句聊天记录无所谓)用户数据报协议,是一个简单的面向数据报的运输层协议,面向无连接。UDP不提供可靠性,数据传输可能发生错序,丢包,但效率较高。一般用于对于实时性要求较高的场合。
6线程之间的通信方式(如何避免ANR)
(1). AsyncTask,其中doInBackground()和onPostExecute(Result)两个方法非常重要
doInBackground() 这个方法运行在后台线程中,主要负责执行那些很耗时的操作,如访问网络。该方法必须重写。(其实这个方法就是在子线程中做耗时操作,通过handler发送到onPostExecute)
onPostExecute(Result) 这个方法运行于UI主线程,在doInBackground(Params…)方法执行后调用,该方法用于接收后台任务执行后返回的结果,刷新UI显示。
(2.)子线程 + handler
在子线程中执行完耗时操作需要刷新UI时,通过handler.sendMessage()发消息给主线程, 然后在主线程Handler中的handleMessage()方法中执行刷新UI操作
7.activity的生命周期
(可见安卓开发艺术与探索) // 开始 重新启动 停止 销毁 暂停
七个,oncreate,onstart,onrestart,onstop,onresume,ondestroy,onpause;(清楚整个周期的过程)
1).启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态(onStart在页面没有获取焦点之前执行, onResume在页面获取焦点时执行,一般情况下网络请求放在onResume方法中,这样做到目的是负责在当前页面上的页面结束后,当前页面也快及时更新数据)。
2).当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3).当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4).当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5).用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6).当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7).用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
Activity 有七个生命周期
一般情况下创建一个activity首先会执行onCreate,onStart,onResume,onPause,onStop,onDestory,这个时候我们一般将访问网络放在onResume里面,
onCreate :activity 第一次创建的时候被执行,
onStart :在启动但没有获取焦点之前执行,无法与用户进行交互
onResume :在获取到焦点的时候执行,同时可以操作页面
onPause :activity正在失去焦点的时候执行
onStop :失去焦点以后执行
onDestory:页面销毁的时候执行,
比如刚刚创建一个activity,首先会执行onCreate, onStart, onResume,这个时候跳转到其他activity,当前activity首先会执行onPause, onStop,(但是如果另外一个activity采用了透明的主题,当前activity不会回调onStop),其他activity执行onCreate, onStart, onResume,这个时候结束掉其他activity,当前activity会执行onRestart, onStart, onResume
8.ArrayList和LinkedList区别
存数据,ArrayList数组存储数据,索引值以下标来搜索,查询比较方,删除增加比较麻烦,但是linkedList以链表式存储数据,对于增删比较方便。
ArrayList和LinkedList在性能上各 有优缺点,都有各自所适用的地方,总的说来可以描述如下:
对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是 统一的,分配一个内部Entry对象。
在ArrayList的 中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
LinkedList不 支持高效的随机元素访问。
ArrayList的空 间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中 间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
9.framgment生命周期?
oncreate,onstart,onrestart,onstop,onresume,ondestroy,onpause,onAttach,onCreateView,onDettach,onDestroyView;(和activity的生命周期比较,会更好)
MyFragment onAttach() 粘贴到activity上
MyFragment onCreate() fragment创建
MyFragment onCreateView() fragment创建自己的视图
MainActivity onCreate()
MyFragment onActivityCreated() 可以处理fragment数据的初始化
MainActivity onStart()
MyFragment onStart()
MainActivity onResume()
MyFragment onResume()
按后退键
MyFragment onPause()
MainActivity onPause()
MyFragment onStop()
MainActivity onStop()
MyFragment onDestoryView() 销毁掉自己的视图
MyFragment onDestory()
MyFragment onDetach() 解除和activity的关系
MainActivity onDestory()
10·图片异步加载怎么做?
三级缓存:
1:首先从强引用中获取(Lrucache),如果强引用中没有,再去软引用中获取(SoftReference),如果软引用再去SD卡获取(SD卡被Dis Lrucache替代掉),如果这三级缓存中都没有,就开启网络去请求图片,请求回来的图片,在加入到强引用中(Lrucache),如果强引用已经满了,这时候,强引用通过Lrucache算法,删除掉一些最近不常用的图片,这时候咱们把这些图片放到软引用里面,(当内存不足到时候软引用就会被被垃圾回收机制回收),如果垃圾回收机制没有,软引用也满了,将不常用的图片移除掉,同时加入到SD卡,(现在被Dis Lrucache替代)
(key 一般使用的是网络请求图片的url,来保证唯一性,一般情况下我会做一下MD5加密,这样做的目的是为了保证不会出现非法字符)
现在SoftReference已经被替代掉,现在我们只使用两级缓存,在加网络, Lrucache, Dis Lrucache
LRC算法:最近最少使用的(内部如何实现的)
强引用: Lrucache
软引用: SoftReference
弱引用:weak(随时被垃圾回收机制回收)
虚引用:phantomreference
可定义图片异步加载工具类,核心方式实现思路如下:
1.先从内存缓存(Map<String,SoftReference<Bitmap>>中获取图片显示
2.获取不到的话从本地SD卡里获取并显示
3.都获取不到的话通过子线程从网络加载图片并保存到内存及SD卡中并通过handler显示
11·service和Thread区别?(概率70%)
Service:是安卓的自大组件之间, Service的开启方式有两种,分别是StartService,和BindService,这两种启动方式的区别是: StartService与Activity没有任何关系,只要开启以后,就一直活跃在后头, BindService与开启的activity有关联,只要activity销毁, Service就会销毁.
Thread:的Java中的线程类,与service没有本质上的关联,在安卓中,2.3以后不允许在主线程进行耗时操作,避免ANR,所以一般情况下,都将耗时操作放在Thread里面,安卓提供了Handler机制来更新UI.(Handler原理)
1).Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2).Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上
12·内存泄露如何解决?(概率90%)
1)、 数据库的cursor没有关闭
2)、 构造adapter没有使用缓存contentview
Listview:性能优化:
1: Listview是需要和适配器配合使用的,常用的适配器有arrayAdapter,SimplerAdapter, SimpleCursorAdapter,BaseAdapter,一般情况下我使用的是继承BaseAdapter,实现它的四个方法,其中最重要的两个方法,getCount,和getView,在不做任何处理的情况下getview每次都重新生成一个view,这样的结果就是很消耗内存,谷歌官网提供了优化listview内存的方法,通过ConvertView的复用和使用ViewHolder来减少findbyid的次数,从而达到控件的复用和减少cpu的消耗,但是因为控件的复用,在加载图片的时候,复用的控件里面有残留的图片,从而造成图片的错位,所以我们必须在初始化的时候设置默认图片来清除缓存的图片,同时在加载的时候图片的时候,如果不进行listview的性能优化,就会造成OOM,所以一般情况下我们会加载二次采样过后的url,同时我们会进行三级缓存的处理,(同上)
二次采样:
既然是二次采样,那当然要分为两步了,下面我们来说说每次采样的主要工作:
1.第一次采样
第一次采样我主要是想要获得图片的压缩比例,假如说我有一张图片是200*200,那么我想把这张图片的缩略图显示在一个50*50的ImageView上,那我的压缩比例应该为4,那么这个4应该怎么样来获得呢?这就是我们第一步的操作了,我先加载图片的边界到内存中,这个加载操作并不会耗费多少内存,加载到内存之后,我就可以获得这张图片的宽高参数,然后根据图片的宽高,再结合控件的宽高计算出缩放比例。
2.第二次采样
在第一次采样的基础上,我来进行二次采样。二次采样的时候,我把第一次bab采样后算出来的结果作为一个参数传递给第BitmapFactory,这样在加载图片的时候系统就不会将整张图片加载进来了,而是只会加载该图片的一张缩略图进来,这样不仅提高了加载速率,而且也极大的节省了内存,而且对于用户来说,他也不会有视觉上的差异
3.代码实现
第一次采样:首先获取new BitmapFactory.Options()获取option对象, inJustDecodeBounds
设置为true只会加载图片的边框进来,并不会加载图片具体的像素点,通过BitmapFactory.decodeFile(filePath, options);来进行第一次加载图片,通过outWidth原图的宽度,通过outHeight获取原图的高,接下来通过图片的跨度和控件的高度来获取一个采样率sampleSize,接下来设置inJustDecodeBounds为false,同时设置缩放比,设置inPreferredConfig的图片的图片格式有(分别为ALPHA_8,RGB_565,ARGB_4444,ARGB_8888),最后进行图片的加载.
衍生的listview优化问题:减少创建View的对象,充分使用contentview,可以使用静态类来处理优化getView的过程 3、Bitmap对象不使用时采用recycle()释放内存 4、Activity中的对象生命周期大于Activity
)Bitmap对象不使用recycle()释放内存
)Activity中的对象生命周期大于Activity;
内存泄露大多数都是由于相同的错误导致的,即:对Context拥有较长时间的引用。
避免Context相关的内存泄露,记住以下事情:
不要保留对Context-Activity长时间的引用(对Activity的引用的时候,必须确保拥有和Activity一样的生命周期)
尝试使用Context-Application来替代Context-Activity
如果你不想控制内部类的生命周期,应避免在Activity中使用非静态的内部类,而应该使用静态的内部类,并在其中创建一个对Activity的弱引用。这种情况的解决办法是使用一个静态的内部类,其中拥有对外部类的WeakReference,如同ViewRoot和它的Winner类那样
GC(垃圾回收)不能解决内存泄露问题
13·程序结束的时候,如何处理Activity的?(概率40%)
记录打开的Activity:(http://zdpeng.iteye.com/blog/1576055)
每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
Activity层数不要太多,太多用户体验太差,手机反应慢,所以在做app的时候,尽量保持不超过3层,第一层main,
14·配置文件中存放什么?(概率60%)
四大组件,意图,权限,第三方key,版本号等
15·NDK是什么?(概率50%)
NDK 是 Native Development Kit 的简称。它是一个工具集,集成了 Android 的交叉编译环境,并提供了一套比较方便的 Makefile ,可以帮助开发者快速开发 C 或是 C++ 的动态库,并自动的将 so 和 java 程序打包成 apk ,在 Android 上运行。Android 上,应用程序的开发,大部分基于 Java 语言来实现。要使用 c 或是 c++ 的程序或库,就需要使用 NDK 来实现。
16百度地图和谷歌地图的优缺点?(概率60%)
优势:
1一打开百度地图页面,显示的就是目前所在城市地图,谷歌地图不然。
2百度地图的界面,百度地图很多都是在显眼位置用文字做提示,一目了然,谷歌界面有点炫,很多用图标来表示,但是用起来相对复杂,不熟悉的用户需要确定这个图标是否是所需要选择的。
而百度地图搜索框下就直接有“公交”“驾车”的选项,界面简洁直接很多,谷歌地图需要点击获取路线,再点击小图标来选择“公交”这些选项,而且图标不够引人注目,使用起来相对复杂些,试想一个很少用网络地图的人分别使用二者地图,那个更方便呢?应该是
百度
,大多数用户通过地图是查询位置-这个地方在哪,周围有什么地物,查询路线-从一个方到另一个地方如何到达,用百度地图,这些问题很容易解决,而用谷歌地图得摆弄一会儿。
3百度地图的查询路线更好,首先还是界面更简洁直接,然后是数据的问题,先不管为他们提供数据的公司如何,刚刚特意同时查了下,同样地起点和终点, 百度地图给出了5条路线,谷歌地图给出的是4条路线,而且百度地图路线的选择时可以选择“较快捷”“少换乘”“少步行”三种方式,更方便。打车费用也直接 显示出来,而且个人体会10元内的打车费用基本正确。
4百度地图有个视野内搜索功能,可以很方便地查找到目标位置,谷歌地图没有。这个很重要。
5一个重要界面布局问题,百度地图是地图视野在左,而谷歌地图是地图视野在右,我们现在时喜欢从左到右看东西啊,这点百度地图更符合用户习惯。(当然也可能是我常用百度地图,所以这么觉得)
PS:刚在知乎上有朋友说到——因“左图右列表”强调的是“地图”,反之强调的是“搜索”;我们发现用户在经过这么些年的教育后,“不在乎”地图在哪边,相对其它体验,这一点影响用户选择服务的权重并不高。
6百度地图已经和都市圈合作推出了部分城市如北京、上海、深圳、广州的三维地图,谷歌地图没有。
7百度地图地图视野上方有个截图功能,可以直接拉框截图,谷歌地图没有。
8以北京实时路况信息为例,直接输入北京查询,百度地图显示的是主城区的实时路况,而谷歌显示的区域很大,包括了密4云、廊坊市了,但是实时路况信息还是显示的主城区,显示路况的彩色条就全挤在一起了,设计得不如百度好。
8使用百度的占大多数,经常可以听到“百度一下啊”的话语。随之带来百度地图的使用率也相对较高。
9百度地图的地图百宝箱、房产、天气等信息。
劣势:
1如果需要从网络地图上获取数据的话,谷歌地图完胜,而且还有谷歌地球在一旁辅助,如虎添翼,从网上各种各样的谷歌地图相关工具软件就可以看出。
2路线查询时输入地点名称却有多个符合条件时,会给出一个下拉菜单给予选择,同一地点谷歌地图提供的数据精确到街道,而百度地图精确到区。
3谷歌地图可以将侧边栏隐藏起来,看到更大的地图视野,而百度地图是点击全屏来显示更大的视野,两种切换方式比起来谷歌的更舒服。
4谷歌地图有个分享链接功能,而且还提供“粘贴 HTML 以便嵌入到网站”这一功能,百度没有。
5界面布局百度地图更简洁,但是色彩搭配上和画面感上谷歌地图更好。
6谷歌的品牌形象占优。
17·安卓的系统架构(概率40%)
应用层:使用Java语言进行开发的一些应用程序
应用框架曾:主要是谷歌发布的一些操作支持的类库(API框架),开发人员可以使用这些类库方便的进行程序开发,但是在开发时必须遵守框架的开发原则
系统运行库层:当使用安卓框架层进行开发时,安卓操作系统会自动使用一些c/c++的库文件来支持所使用的各个组件,使其可以更好的为程序服务;
Linux内核层:安卓操作系统主要是基于Linux内核,程序的安全性,驱动程序,进程管理等都由Linux内核提供。
18.listView优化(概率60%)
1)、convertView复用,对convetView进行判空,当convertView不为空时重复使用,为空则初始化,从而减少了很多不必要的View的创建
2)定义一个ViewHolder,封装Listview Item条目中所有的组件,将convetView的tag设置为ViewHolder,不为空时通过ViewHolder的属性获取对应组件即可
3)、当ListView加载数据量较大时可以采用分页加载和图片异步加载
19·简述音乐播放的方式与区别?(概率20%)
1):MediaPlayer:主要用于播放音频,可以播放视频,但是一般不用其进行视频播放。
2):SoundPool:主要用于播放一些短促的声音片段,主要优势是cpu资源占有量低,反应延迟小。
20·JSON的结构?(概率20%)
json是一种轻量级的数据交换格式,
json简单说就是对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构
1、对象:对象表示为“{}”扩起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
2、数组:数组在json中是中括号“[]”扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。
经过对象、数组2种结构就可以组合成复杂的数据结构了。
本文出自 优快云:
https://blog.youkuaiyun.com/dangai0201/article/details/78207863