1. 使用匿名内部类的好处是什么?
1. 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据;
2. 使用匿名内部类定义回调函数,节省代码;
3. 内部类可以对同一个包中的其他类隐藏起来;
2. Service 有哪两种启动方式?
1. 通过 startService
Service 会经历 onCreate -> onStart,stopService 的时候直接 onDestroy,如果是调用者(ServiceHolder)自己直接退出而没有调用 stopService 的话,Service 会一直在后台运行,下次 ServiceHolder 再起来可以 stopService。
2. 通过 bindService
Service 只会运行onCreate,这个时候 ServiceHolder 和 Service 绑定在一起 ServiceHolder 退出了,Srevice 就会调用onUnbind -> onDestroyed 所谓绑定在一起就共存亡了。
3. Looper 和 Handler 的关系
答:我的理解就是,looper 负责维护一个消息队列(MessageQueue),并且处于一个死循环的线程当中,每隔一段时间就去消息队列中取出一个消息,然后处理消息,处理完成之后去取下一个,如果消息队列为空的话,线程则会阻塞等待,而 handler的话是可以通过 post 方法向消息队列里面添加消息的,这样就能实现对异步消息的处理!
4. 什么时候用 Context,什么时候用 ApplicationContext?
1. 启动 service(服务)、发送广播、或者是加载资源(dimen、color、attrs、drawable等)时,ApplicationContext和四大组件的 context 都可用;
2. 在绑定 service(服务)和注册广播接收者时,除了广播接收者本身的 context 不能用以外,其他都可以;
3. 在显示 dialog(弹窗)、启动其他 activity 或者是加载布局文件的时候,就只能用 activity 的 context;
5. 如何解决/避免 OOM 问题?
定义:当进程占用内存值高于默认阈值(32M,不同机器略有差异)时,会报 OOM 异常;
1. 注意对资源文件的使用和释放,比如说图片资源,在加载下一张图片时,若上一张图片不需要用了,就将其释放掉,避免无谓的占用内存;
2.避免handler高频 + 重复 + 耗时使用,必须要用的话,要用软引用或者弱引用;
3. 在使用 Listview、Girdview、RecycleView 等列表控件时,注意使用 ViewHolder 实现对 ConvertView 的复用;
4. 根据图片大小和分辨率将它放在正确的 drawable 目录下;
5.避免使用枚举从而消耗大量内存;
6. 如何解决/避免内存泄漏问题?
定义:长生命周期的对象持有短生命周期的对象导致短生命周期的对象无法及时释放;
1. 打开和关闭这两个动作一定要配对使用,例如cursor + file + db(open 和close)、runnable(post 和 removecallbacks)、broadcastReceiver(regist 和 unregist)、service(bind 和 unbind);
2. 对于内部有耗时操作的handler对象,考虑使用软引用或者弱引用;对于强引用的对象,在确定不需要使用后,可以人为置空,有利于 GC 回收;
3. 在显示 dialog、toast 或 new 一个新的对象(比如 new 一个 runnable)时,适当考虑使用单例模式,避免多次重复显示、重复 new 对象并降低内存消耗;
6. 如何解决/避免ANR问题?
定义:主线程在5秒内没有响应输入事件,BroadcastReceiver 没有在10秒内完成返回;
日志路径(保存10条):/data/system/dropbox/
日志路径(保存3天): /data/anr/
1. 在执行耗时操作(例如网络请求、列表获取大量数据、列表排序、删除大量数据、加载复杂布局等)时,尽量将其放在异步线程中执行,避免主线程阻塞!
2. 对于一个点击或者滑动事件,如果响应比较耗时,也可考虑将这个耗时操作采用单例模式,就是如果上次点击或者滑动事件未执行完成,就将此次点击事件return掉,避免重复执行导致响应时间更长从而产生 ANR;
7. Android 四种内部类
public class Color {
static class Red {
public static void showItSelf() {
System.out.print("我是红色,我是静态内部类");
}
}
class Green {
public void showItSelf() {
System.out.print("我是绿色,我是成员内部类");
}
}
public void function() {
class Yellow {
public void showItSelf() {
System.out.println("我是黄色,我是局部内部类");
}
}
new Yellow().showItSelf();
}
}
上述代码中:
1. 静态内部类(Red 类);
2. 成员内部类(Green 类);
3. 局部内部类(Yellow 类);
4. 匿名内部类(这个就不赘述了,没有名字的类也不好描述);
8. 接口 Interface 的作用
1. 多个 Interface 可以同时被一个类继承的特性可以弥补 Java 单继承的缺点,增强其可扩展性;
2. 定义公共接口和公共回调方法可以规范代码;
9. 静态注册广播和动态注册广播优劣?
1. 静态广播(常驻型广播):在 AndroidManifast 里面注册,就算是应用程序关闭了,如果有广播信息来,写的广播接收器同样的能接收到;
使用场景:在应用程序 启动之前 或 关闭之后 都得监听的
优点:不受应用生命周期的影响
缺点:耗费 cpu、电量等资源
2. 动态广播(非常驻型广播):在 activity 里面注册,当广播所依赖的应用程序生命周期结束了,广播自然就没有了;
使用场景:只需要在应用程序运行时监听的
优点:优先级高,电量、cpu 等资源占用少
缺点:代码量大一些,有应用程序必须处于运行状态的限制条件
10. Android 跨进程通讯有哪些实现方法?
1. 通过 Intent 启动其他应用的组件 Activity,Service,BroadCastReceiver,将数据存储在 Bundle 中,然后设置在 Intent 中,再 SendBroadCast 或者 StartActivity;
2. 利用 SharedPreference、Setting 实现进程间数据共享,利用键值对存储信息(缺点:存在并发风险、文件勿删风险、应用清除数据风险等);
3. 利用 ContentProvider 实现进程间数据共享;
4. 通过 AIDL 服务实现数据进程间通讯,AIDL是Android中IPC(Inter-Process Communication)方式中的一种,全称是 Android Interface Definition Language,也就是说,AIDL 实际上是一种接口定义语言;
下一篇:Android 开发个人的一些积累(二)