一、Android中的底层图形类:android.graphics提供接口。
1.drawable:通用的图形对象,用于装载常用格式的图像。我们可以理解成一个用来放画的---画框。
2.Bitmap:(位图)我们可以把它看做一个画架。
3.canvas:画布。
二、Bitmap引起的OOM问题:
OutOfMemory(内存溢出)。Android会为每个App分配一个独立的工作空间,或者说分配一个单独的dalvik虚拟机,这样每个App可以相互独立运行而不互相影响。
避免BItmap引起的OOM:
(1)采用低内存占用量的编码方式:比如Bitmap.Config.ARGB_8888(8位,一个像素占四个字节)是默认值,我们可以修改成Bitmap.Config.ARGB_4444(4位,占两个字节)。
(2)图片压缩:
(3)及时回收图像。
(4)通过softReference引用方式管理图片资源。
我们可以这样定义:map里面的键是用来放图片地址的,既可以使网络图片地址,也可以使sdcard图片地址,map里面的值是持有软引用的Bitmap。
Map
如何具体加载图片:步骤:(1)先通过URL查看缓存中是否有图片,如果有,则直接去缓存中取得,如果没有,则开线程重新去网络加载。
(2)下载完了之后,就把图片放在缓存里面,方便下次可以直接从缓存中取得。
(5)内存缓存技术:在Android中,有一个叫做LruCache类专门用来做图片缓存处理的。
它有一个特点:当缓存的图片达到了预先设定的值得时候,那么近期使用次数最少的图片就会被回收掉。
步骤:(1)要先设置缓存图片的内存大小,一般设置手机内存的1/8.
手机内存的获取方式:int MaxMemory = (int)(Runtime.getRuntime().maxMemory()/1024);
(2)LruCache里面的键值对分别是URL和对应的图片。
(3)重写了一个叫做sizeOf的方法,返回的是图片数量。
(4)分别有清空缓存,添加图片到缓存,从缓存中取得图片,从缓存中移除图片。移除和清除缓存是必须要做的事情,因为图片缓存处理不当就会引起OOM。
clearCache(),addBitmapToMemory(),getBitmapFromMEMCache(),removeIamgeCache()。
二、Service的onStartCommand()方法有几种返回值?
答:四种。
(1)start_Stiky:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。系统会尝试重新创建该服务。
(2)start_Not_Stiky:非粘性的,系统不会自动重启该服务。
(3)start_deleliver_intent:重传Intent,系统会自动重启该服务,并将Intent的值传入。
(4)start_stiky_compatibility:不保证服务被kill后一定能重启。
三、如何让自己的广播只让自己指定的app接收?
(1)自己的应用(A)在发送广播的时候给自己发送的广播自定义权限,然后在AndroidManifest中声明。
(2)其他应用(B)如果想要接收该广播,那么就必须知道应用A广播使用的权限。然后在应用B的清单文件中配置。
四、为什么要用ContentProvider,它和SQL有什么区别?
答:ContentProvider屏蔽了数据存储的细节,内部实现对用户完全透明,用户只需要关心操作数据的uri就可以了,ContentProvider可以实现不同app之间数据共享。
SQL也有正删改查的方法,但是SQL只能查询本应用下的数据库,而contentProvider还可以增删改查本地文件,XML文件的读取等。
五、Android中布局的优化措施:
(1)尽可能减少布局的嵌套层级。
(2)不用设置不必要的背景,避免过度绘制。
(3)使用include标签复用相同的布局代码。
(4)使用merge标签减少视图层级结构。
(5)通过viewStub实现View的延迟加载。
六、android:layout_gravity和android:gravity的区别?
第一个是让该布局在其父控件中的布局方式,第二个是该布局布置其字对象的布局方式。
七、ListView如何提高其效率?
(1)复用ConvertView。
(2)自定义静态类ViewHolder。
(3)使用分页加载。
(4)使用WeakReference引用ImageView对象。
八、当ListView数据集改变后,如何更新ListView?
使用该ListView的adapter的notifyDataSetChanged()方法。该方法会使ListView重新绘制。
九、ListView如何实现分页加载?
(1)设置ListView的滚动监听器:setOnScrolListener(new OnScrollListener{......})
在监听器中有两个方法:滚动状态发生变化的方法(onScrollStateChanged)和ListView被滚动时调用的方法(onScroll)。
(2)在滚动状态发生改变的方法中,有三种状态:
手指按下移动的状态:SCROLL_STATE_TOUCH_SCROLL;//触摸滑动
惯性滑动:SCROL_STATE_FLING;//滑翔
静止状态:SCROLL_STATE_IDLE;静止
对不同的状态进行处理:
分批加载数据,只关心静止状态:关心最后一个可见的条目,如果最后一个可见条目就是数据适配器(集合)里的最后一个,此时可加载更多的数据。
在每次加载的时候,计算出滚动的数量,当滚动的数量大于总数量的时候,可以提示用户无更多数据了。
十、ListView显示多种类型的条目:
ListView显示的每个条目都是通过baseAdapter的getView来展示的,理论上我们可以让每个条目都是不同类型的view,除此之外,adapter还提供了getviewtypeCount()和
getItemViewType()两个方法,在getView方法中我们可以根据不同的ViewType加载不同的布局文件。
十一、ListView如何定位到指定位置?
可以通过ListView提供的lv.setSelection()方法。
十二、ListView中如何优化图片?
答:1.处理图片的方式:(1)使用options保存图片大小,不要加载图片到内存中去。
(2)对图片一定要经过图片压缩尤其是比较大的图片。
(3)WeakReference保存图片。
(4)在getView中做图片转换时,产生的中间变量一定及时释放。
2.异步加载图片基本思想。
(1)先从内存中获取图片显示(内存缓冲)。
(2)获取不到的话从SD卡里面获取(SD卡缓冲)。
(3)都获取不到的话从网络下载图片并保存到SD卡同时加入内存并显示(视情况看是否要显示)。
原理:优化一:先从内存中加载,没有则开启线程从SD卡或网络中获取,这里注意从SD卡获取图片是放在子线程里执行的,
否则快速滑屏的话会不够流畅。
优化二、与此同时,在adapter里会有个busy变量,表示listview是否处于滑动状态,如果是滑动状态则仅从内存中获取图片,没有的话无需再开启线程去外存或网络获取图片。
优化三、ImageLoader里的线程使用了线程池,从而避免了过多线程频繁创建和销毁。在从网络获取图片时,先是将其保存到sd卡,然后再加载到内存,这么做的好处是在加载到内存时可以做个压缩处理,以减少图片所占内存。
十三、ListView中图片错位的问题是如何产生的?
图片错位问题的本质源于我们的listView使用了缓存convertView,假设一种场景,一个listview一屏显示九个item,那么在拉出第十个item的时候,事实上该item是重复使用了
第一个item,也就是说在第一个item在从网络中下载图片并最终要显示的时候,其实该item已经不在当前显示区域了,此时显示的后果将可能在第十个item上输出图像,这就导致了图片错位的问题。所以解决之道在于可见则显示,不可见则不显示。
十四、scrollView嵌套listview方式除了测量还有什么办法?
1.手动代码设置listView高度。
动态设置listview高度。
2.自定义可适应的scrollView的listView。
自定义一个类继承自ListView,通过重写其onMeasure方法达到对scrollView适配的效果。
十五、JNI&NDK
1.在Android中如何调用C语言?
JNI的方式,Java Native Interface。在Android开发目录的libs目录下添加xxx.so文件。在Java代码需要通过System.loadLibrary(libName);加载so文件。同时C语言中的方法在Java中必须以native关键字来声明。普通Java方法调用这个native方法接口,虚拟机内部自动调用C文件中对应的方法。
2.请介绍一下NDK?
(1)NDK是一系列工具的集合。NDK提供了一系列的工具,帮助开发者快速开发C或C++的动态库,并能自动将so和Java应用一起打包成apk。
(2)NDK提供了一份稳定,功能有限的API头文件声明。
3.JNI调用两个常用的参数:
第一个是指向虚拟机对象的指针,是一个二级指针。里面封装了很多方法和二级变量供我们使用。
第二个代表着调用该方法的Java对象的C语言表示。
十六、Fragment的add和replace方法的区别?
fragment本身并没有add和replace方法,这里应该理解为fragmentManager的replace和add方法切换Fragment时有什么不同。
add方法添加fragment要结合hide和show方法使用。将要显示的show出来,不显示的hide起来。这个过程Fragment的生命周期无变化。
通过replace切换fragment,每次都会执行上一个fragment的onDestroyView,新Fragment的onCreateView,onStart,onResume方法。
十七、什么情况下会导致内存泄漏?
内存溢出的几点原因:
1.资源释放问题。
长期保持某些资源,如Context,Cursor,IO流的引用,资源得不到释放。
2.对象内存过大问题。
3.static关键字的使用问题。
4.线程导致内存溢出。
十八、Android中如何捕获未捕获的异常?
1.自定义一个Application,比如MyApplication继承Application实现UnCaughtExceptionHandler.
2.覆写UNCaughtExceptionHandler的onCreate和UNCaughtException方法。
3.在AndroidManifest中配置该Application。
十九、Android中屏幕适配:
1.dp.
2.dimens
3.layout
4.weight
5.java代码适配
6.尽量使用线性布局,相对布局