您的位置:首页 > 职场人生

android面试总结二

2015-05-19 12:36 260 查看
6. Handler及Looper的使用方法及使用场景

从这些文档中我们大概了解到handler干了些什么:

  运行在某个线程上,共享线程的消息队列;
  接收消息、调度消息,派发消息和处理消息;
  实现消息的异步处理;

7. AysnTask的使用方法及使用场景

1、对于耗时的操作,我们的一般方法是开启“子线程”。如果需要更新UI,则需要使用handler
2、如果耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。在这种情况下我们就可以考虑使用类AsyncTask来异步执行任务,不需要子线程和handler,就可以完成异步操作和刷新UI。
3、AsyncTask:对线程间的通讯做了包装,是后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。
4、使用方法:共分为两步,自定义AsyncTask,在耗时的地方调用自定义的AsyncTask。可以参照以下代码示例。
step1:继承AsyncTask<Params,Progress,Result>
Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。
Progress:子线程执行的百分比
Result:返回值类型。和doInBackground()方法的返回值类型保持一致。
step2:实现以下几个方法:执行时机和作用看示例代码,以下对返回值类型和参数进行说明
onPreExecute():无返回值类型。不传参数
doInBackground(Params... params):返回值类型和Result保持一致。参数:若无就传递Void;若有,就可用Params
publishProgress(Params... params):在执行此方法的时候会直接调用onProgressUpdate(Params... values)
onProgressUpdate(Params... values):无返回值类型。参数:若无就传递Void;若有,就可用Progress
onPostExecute(Result result) :无返回值类型。参数:和Result保持一致。
step3:在调用自定义的AsyncTask类中生成对象;
执行 :对象.excute(Params... params);
小注:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground=\'#\'" onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
参照:http://www.cnblogs.com/suinuaner/archive/2013/04/11/android_fifty.html
8. 几种Layout,padding/margin/gravity/weight各自含义

gravity:属性是对该view 内容的限定

layout_gravity:是用来设置该view相对与起父view 的位置.

padding:填充的意思,指的是view中的content与view边缘的距离

margin:表示的是view的边缘与parent view的边缘的距离

margin一般用来描述控件间位置关系,而padding一般描述控件内容和控件的位置关系。

9. 自定义组件(自定义adapter的使用)

Android提供了用于构建UI的强大的组件模型。两个基类:View和ViewGroup。

可用Widget的部分名单包括Button, TextView, EditText, ListView, CheckBox,RadioButton, Gallery, Spinner,以及一些有特别作用的组件: AutoCompleteTextView, ImageSwitcher和 TextSwitcher。

可用的布局有:LinearLayout,FrameLayout,RelativeLayout,AbsoluteLayout,GridLayout (later on api level 14 or v7-support)

基本做法:

1. 继承自View或View的子类

2. 重写父类的一些方法,如:onDraw(),onMeasure(),onLayout()等

3. 使用自定义的组件类。



完全自定义组件:



1. 最普通的作法是,继承自View,实现你的自定义组件



2. 提供一个构造函数,采用有属性参数的,也可以使用自定义属性

3. 你可能想在组件中创建自己的事件监听器,属性访问器和修改器,或其他行为

4. 几乎肯定要重写onDraw(),onMeasure()。默认onDraw()什么也没作,onMeasure()则设置一个100x100的尺寸。

5. 根据需要重写其他方法 ...

10. ANR异常,OOM异常及如何解决,内存泄露的含义:

(1)ANRs (“Application Not Responding”),意思是”应用没有响应“。

在如下情况下,Android会报出ANR错误:

– 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件

– BroadcastReceiver 没有在10秒内完成返回

通常情况下,下面这些做法会导致ANR

1、在主线程内进行网络操作

2、在主线程内进行一些缓慢的磁盘操作(例如执行没有优化过的SQL查询)

应用应该在5秒或者10秒内响应,否则用户会觉得“这个应用很垃圾”“烂”“慢”…等等

逻辑应该是

1. new出一个新的线程,进行数据请求

2. 获取数据后,调用handler.sendMessage方法

3. 在handler的handle()方法中更新UI

[java] view plaincopy

private Thread mthread;

private Handler mhandler;

oncreate:

mthread = new Thread(runnable);//这里是在主线程中创建一个子线程,不会阻塞UI

mthread.start();

private Runnable runnable = new Runnable (){

void run(){

//做耗时的数据处理

//处理完毕

mhandler.sendEmptyMessge(1000);//这里发消息通知UI可以更新了

}

};

mhandler = new Handler(){

void handleMessgae(Message msg){

if(msg.what == 1000){

//更新UI

}

super.handlMessgae();

}

};

(2)

1、OOM的具体原因。
基于Android开发应用时,可能会时常出现Out Of Memory 异常

①一个进程的内存可以由2个部门组成:java 使用内存 ,C 使用内存 ,这两个内存的和必需小于16M,不然就会出现各人熟悉的OOM。
②一旦内存分配给Java后,以后这块内存纵然开释后,也只能给Java的使用,这个估计跟java虚拟机里把内存分成好几块进行缓存的原因有关,反正C就别想用到这块的内存了,所以要是Java突然占用了一个大块内存,纵然很快开释了,C能使用的内存 = 16M - Java某一瞬间占在的最大内存。
③而Bitmap的生成是路程经过过程malloc进行内存分配的,占用的是C的内存。
根据这个原理那么我们就可以有效的避免OOM的出现,具体我们可以做以下一些额外的工作来有效避免OOM。

2、几点建议。
①对于java中不再使用的资源需要尽快的释放,即设置成null,不要老是指望垃圾回收器为你工作。如果不设置成null,那么资源回收会受到一定的影响。
②尽量少用static方法和static成员。因为static的方法或成员被外部使用的话,而外部的牵引对象没有对其进行释放的话那么整个static的类都不会被释放,也就造成内存泄漏。
③对于不再使用的bitmap应该手动调用recycle方法,并且设置成null。图片还要尽量使用软引用方式,这样可以加快垃圾回收。
答:怎么解决OOM,通常OOM都发生在需要用到大量内存的情况下(创建或解析Bitmap,分配特大的数组等),在这样的一种情况下,就可能出现OOM,据我现在了解到,多数OOM都是因为Bitmap太大。所以,这里我就专门针对如何解决Bitmap的OOM。其实最核发的就是只加载可见范围内的Bitmap,试想这样一种情况,在GridView或ListView中,数据量有5000,每一屏只显示20个元素,那么不可见的,我们是不需要保存Bitmap在内在中的。所以我们就是只把那么可见的Bitmap保留在内存中,那些不可见的,就释放掉。当元素滑出来时,再去加载Bitmap。(一:主动释放Bitmap的内存,二:设计cache).
(3)内存泄露的含义是程序在运行时动态的分配内存空间,但是用完之后并未释放,随着时间的延长,内存会被渐渐地消耗,知道被耗尽,直接导致整个系统崩溃。这里的内存并非是物理上的,而是虚存的大小。
导致内存泄露的原因有很多:

1.程序员在使用 malloc 或 new 申请内存空间,但是在程序中没有使用 free 或 delete 释放。

2.程序在运行时不停地申请内存,直到程序执行结束才释放。严格意义上是没有内存的泄露。但是从服务器的角度上来说,程序是不断地消耗内存。这种情况成为隐式内存泄露。

3.类在构造函数中分配内存,在析构函数中没有释放,这种情况内存只会泄露一次。

4.系统资源泄露,程序使用socket , handle 等,没有使用相应的函数释放,会导致系统资源的浪费。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: