android面试宝典

时间:2023-03-09 18:41:56
android面试宝典

一.listview的优化:

首先要知道getview实际就是个for循环。

我们重写的getview方法中本身有一个convertview,因为只需要保留能够显示的最大个数的view即可,所以:

第一步就是判断convertview是否为空,是空就inflater一个view,并且将findviewid的结果赋给holder

然后convertView.setTag(holder)(将holder与convertview绑定);

不是空的时候就直接取出holder(holder = (Holder) convertView.getTag();)(新的convertview通过复用的方式使用消失的convertview);

ps: holder的作用就是保存findviewbyid的结果。

再优化的话就是分页加载和分批加载一起用。

当listview嵌套gridview时,优化adapter时,要把gridview的adapter也加到listholder中;

eg:

 if (null == listHolder.gridAdapter) {
listHolder.gridAdapter = new MyGridAdapter(listData.get(position).getImgs());
listHolder.gridView.setAdapter(listHolder.gridAdapter);
} else {
listHolder.gridAdapter.update(listData.get(position).getImgs());
}
 update是自己写的方法
 public void update(List<String> gridData) {
this.gridData = gridData;
notifyDataSetChanged();
} 二。加载图片带来的oom
picasso 
1.在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。 
2.使用复杂的图片压缩转换来尽可能的减少内存消耗 
3.自内存和硬盘二级缓存功能
4.Adapter的重用会被自动检测到,Picasso会取消上次的加载
5.虽然recycle()从源码上看,调用它能立即释放Bitmap,但它并没立即释放内存。所以我们还需手动设置为NULL。
三static带来的oom
 第一,应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。
第二、Context尽量使用Application Context,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。
第三、使用WeakReference代替强引用。比如可以使用WeakReference<Context> mContextRef;
四 context带来的oom,一部分同上;
不建议将AsyncTask作为内部类使用
 第一、将线程的内部类,改为静态内部类。。
 第二、在线程内部采用弱引用保存Context引用。
五AsyncTask

不建议将AsyncTask作为内部类使用(double speaking)
AsyncTask<Params, Progress, Result>
Params 参数,progress(integer) 进程,result 结果;

1、onPreExecute():UI线程里面调用,最先调用。我们在这个方法里面通常显示一个等待框。

2、doInBackground(Params...):运行在后台线程,在这个方法里面,去做耗时的事情,比如下载访问网络,操作文件等。在这个方法里调用publishProgress(Progress...)来调用当前任务的进度,对应的onProgressUpdate(Progress...)方法会被调用,onProgressUpdate是运行在UI线程的。

3、onProgressUpdate(Progress...):运行在UI线程,在调用publishProgress()方法之后。这个方法用来在UI上显示任何形式的进度。

4、onPostExecute(Result):当task结束后调用,它运行在UI线程。

5、取消一个task,我们可以在任何时候调用cancel(Boolean)来取消一个任务,当调用了cancel()方法后,onCancelled(Object)方法就会被调用,onPostExecute(Object)       方法不会被调用,在doInBackground(Object[])方法中,我们可以用isCancelled()方法来检查任务是否取消。

局限性:

1.AsyncTask实例必须在UI线程中创建(创建Handler对象时需要当前线程的Looper,所以为了以后能够通过mHandler将执行环境从后台线程切换到主线程(即在主线程中执      行handleMessage方法),我们必须使用主线程的Looper,因此必须在主线程中创建mHandler。这也就解释了为什么必须在主线程中加载AsyncTask类,

是为了完成mHandler    这个静态成员的初始化工作。(onPostExecute方法就是利用的handler))

2.execute(Params...)方法必须在UI线程中调用(只能调用一次execute方法)

AsyncTask默认使用串行方式,m.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)实现并行方式;

3.一个任务只能被执行一次。