Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都各有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。 见文章:https://www.jianshu.com/p/ecfcc9fb1de7 见文章:https://www.jianshu.com/p/77c882f47b29 见文章:https://www.jianshu.com/p/8a775d747c47 见文章:https://www.jianshu.com/p/702eddcac053 见文章:https://www.jianshu.com/p/59f98076b382 见文章:https://www.cnblogs.com/ityouknow/p/5603287.html 见文章:https://blog.csdn.net/sinat_38259539/article/details/71799078 见文章:https://www.cnblogs.com/yangming1996/p/9295168.html 使用泛型的意义在于 (转自:https://www.jianshu.com/p/3a01dee87561) 封装的意义在于保护或者防止代码(数据)被我们无意中破坏。 继承: 是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类能调用父类的非private修饰的成员,同时还可以自己添加一些新的成员,扩充父类,甚至重写父类已有的方法,使其表现符合子类的特征。 继承的好处: 继承的弊端: 继承特点: 注:封装和继承其实有一个共同的目的就是代码重用。 多态: 多态是同一个行为具有多个不同表现形式的能力。多态性是对象多种表现形式的体现 方法的重载和重写都体现了多态性。 见文章:https://blog.csdn.net/qq_31622345/article/details/78686559 线程池:https://www.jianshu.com/p/0f7f3e353dcf 原子性:… 见文章:hashmap面试题 和 原理、hashmapj基本实例 : ArrayList小结 见文章:https://www.cnblogs.com/lierabbit/p/8383683.html 转自:https://www.jianshu.com/p/64734a935588 HashSet,存储object的集合,既然是集合,就不允许有重复元素。判断两个元素是否相同,是由hashCode与equals方法共同完成的。 见文章:链接 见文章:https://www.cnblogs.com/cold-windy/p/11514977.html 见文章:https://blog.csdn.net/vip97yigang/article/details/78306837 见文章:https://www.jianshu.com/p/cf260703f8ff 见文章:https://blog.csdn.net/github_37130188/article/details/89788571 1、冷启动 视频:https://www.bilibili.com/video/BV1f7411p72Q?from=search&seid=8899746014938436225 见文章:https://blog.csdn.net/qq_33275597/article/details/93849695 设计模式的七大原则:https://www.cnblogs.com/neverth/p/11760931.html 这里逻辑就很简单了,直接调用了sendMessageAtTime方法,第一个参数为Message,第二个参数为SystemClock.uptimeMillis() + delayMillis,其中delayMillis为延时的时间,单位为毫秒,SystemClock.uptimeMillis() 为开机到现在的时间(不包括休眠时间),单位为毫秒。第二个参数主要是决定该Message在MessageQueue的顺序,比如现在开机时间为100s,发送一个延时20s的消息,则两者之和为120s; 过了5秒,又发了一个延时5s的消息,则两者只喝为105+5 = 110s。 题目:Android中,有哪些是基于Handler来实现通信的? 见文章:https://blog.csdn.net/augfun/article/details/82343249 见文章:https://www.runoob.com/java/java-operators.html 见文章:https://jingyan.baidu.com/article/495ba84109665338b30ede98.html 基本类型:byte 二进制位数:8 基本类型:short 二进制位数:16 基本类型:int 二进制位数:32 基本类型:long 二进制位数:64 基本类型:float 二进制位数:32 基本类型:double 二进制位数:64 基本类型:char 二进制位数:16 视频:https://www.bilibili.com/video/BV1wz4y197XD?from=search&seid=1188900803975595839 问题: 见文章:https://www.jianshu.com/p/704cac3eb13d 此时的生命周期跟清单文件里的配置有关系。 1、通常情况用户退出一个 Activity 只需按返回键,我们写代码想退出 activity 直接调用 finish()方法就行。 Service 有绑定模式和非绑定模式,以及这两种模式的混合使用方式。不同 的使用方法生命周期方法也不同。 一、IntentService 简介 在 Android 中如果想将自己应用的数据(一般多为数据库中的数据)提供 给第三发应用,那么我们只能通过 ContentProvider 来实现了。 ContentProvider 屏蔽了数据存储的细节 ,内部实现对用户完全 透明,用户只需要关心操作数据的 uri 就可以了,ContentProvider 可以实现不同 app之间共享。Sql 也有增删改查的方法, 但是 sql 只能查询本应用下的数据库。而 ContentProvider 还可以去增删改查本地文件. xml 文件的读取等。 a. ContentProvider 内容提供者,用于对外提供数据 Android 中,系统为多媒体类型的文件(比如图片、音频、视频等)建立了 ①设 置 ListView 的 滚 动 监 听 器 : setOnScrollListener(newOnScrollListener{….})在监听器中有两个方法: 滚动状态发生变化的方法(onScrollStateChanged)和 listView 被滚动时调用的方法(onScroll) 通常情况下我们不会在 ScrollView 中嵌套 ListView,但是如果面试官非 让我嵌套的话也是可以的。 在使用内存的时候, Parcelable 类比 Serializable 性能高, 所以推荐使用 Parcelable 类。 OOM 内存溢出,想要避免 OOM 异常首先我们要知道什么情况下会导致 OOM 异常。 在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用 户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application NotResponding ) 对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设 计很重要,这样,系统不会显示 ANR 给用户。 共享内存(变量); Android 应用的开发语言为 Java,每个应用最大可使用的堆内存受到 Android 系统的限制 1、注意资源回收,像数据库,输入输出流,定位操作这样的对象,要在使 用完及时关闭流。 src 目录是源代码目录,所有允许用户修改的 java 文件和用户自己添加的 java 文件都保存在这个目录中 一、进程间的通信方式 )管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只 二、线程间的通信方式 *读写锁允许多个线程同时读共享数据,而对写操作是互斥的。 *条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。 # 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量 ① aidl 是 Android interface definition Language 的英文缩写, 意思Android 接口定义语言。 见文章:https://www.cnblogs.com/whycxb/p/9755012.html 见文章:https://gitee.com/all-about-git 见文章:https://blog.csdn.net/qq_24946689/article/details/105365912Android和java知识点总结(均为网络转载,方便复习和学习)
1 java基础部分
1.1 JVM部分
1.2 JVM内存区域(运行时数据区域):
1.3 JVM内存区域(虚拟机栈):
1.4 JVM内存区域(程序计数器):
1.5 JVM内存区域(本地方法栈):
1.6 JVM内存区域(Java 堆):
1.7 JVM内存区域(方法区):
1.8 java类加载机制
1.9 反射
1.10 注解
1.11 泛型
1,适用于多种数据类型执行相同的代码(代码复用)
2, 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
见文章:https://www.jianshu.com/p/986f732ed2f11.12 Java面向对象的三种特性
(1)首先,要引申出类:类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
(2)面向对象共有三个特征:封装,继承,多态。
封装: 把一些属性和方法封装起来,形成一个类;可以隐藏实现细节。提高了代码的复用性。也提高了安全性。
封装的作用:
1、提高了代码的复用性。
2、隐藏了实现细节,还要对外提供可以访问的方式。便于调用者的使用。这是核心之一,也可以理解为就是封装的概念。
3、提高了安全性。
1.提高了代码的可维护性
2.提高了代码的复用性
3.让类与类之间产生了继承关系
1.类与类之间的耦合度过高
1.java中类只能够单继承,不能多继承,可以多层继承
Java作为面向对象的语言,同样可以描述一个事物的多种形态。
类中多个方法的重载叫多态,父子类中方法的覆盖也叫多态。
多态有方法的多态和对象的多态(一个对象多种形态)。1.13 Java面向对象面试题总结
1.14 多线程
面试题见文章:https://www.jianshu.com/p/00fb4d37d9cf1.15 多线程三大特性
可见性:…
有序性:…
见文章:https://www.cnblogs.com/javatalk/p/9917348.html1.16 HashMap
import java.util.HashMap; /** * Created by landyChris on 2017/10/29. */ public class FHashMap<K,V> implements Map<K,V> { public static void main(String[] args) { // FHashMap FHashMap =new FHashMap(); // FHashMap.put("速度和咯技术的好的",99999); // FHashMap.put("速度和咯技术的好的",3333); // FHashMap.put("快速度和咯技术的好的",555555); // FHashMap.put("加快速度和咯技术的好",99444999); // System.out.println(FHashMap.get("和咯技术的好的").toString()+";size="+ FHashMap.size); HashMap hashMap=new HashMap(); hashMap.put("1","2222"); hashMap.put("1","2222w"); hashMap.put("1","2222d"); hashMap.put("1","2222d2"); hashMap.put("2","2222d2"); System.out.println(hashMap.size()); } //默认容量 private static int defaultLength = 16; //默认加载因子 private static double defualtLoaderFactor = 0.75; private Entry<K,V> table[] = null; private int size = 0; public FHashMap() { this(defaultLength,defualtLoaderFactor); } public FHashMap(int length, double loaderFactor) { defaultLength = length; defualtLoaderFactor = loaderFactor; table = new Entry[defaultLength]; } private int hash(K k) { int m = defaultLength; int i = k.hashCode() % m; System.out.println("i:"+i); return i > 0 ? i : -i; } @Override public V put(K key, V value) { int index = hash(key); Entry<K,V> entry = table[index]; if(entry == null) { table[index] = new Entry(key,value,null); size ++; }else { table[index] = new Entry(key,value,entry); System.out.println("oldVlaue=" + table[index].next.getValue()+"newValue="+table[index].getValue()); } return table[index].getValue(); } @Override public V get(K key) { int index = hash(key); if(table[index] == null) { return null; } return find(table[index],key); } private V find(Entry<K, V> entry, K key) { if(key == entry.getKey()||key.equals(entry.getKey())) { if(entry.next != null) { System.out.println("oldValue1=" + entry.next.getValue()); } return entry.getValue(); }else { //不相等的时候,就直接递归去取下一个值 if(entry.next != null) { System.out.println("oldValue2=" + entry.next.getValue()); return find(entry.next,key); } } return null; } @Override public int size() { return size; } class Entry<K,V> implements Map.Entry<K,V> { K k; V v; Entry<K,V> next; public Entry(K k,V v,Entry<K,V> next) { this.k = k; this.v = v; this.next = next; } @Override public K getKey() { return k; } @Override public V getValue() { return v; } } }
1.17 Arraylist
ArrayList是List接口的一个可变大小的数组的实现
ArrayList的内部是使用一个Object对象数组来存储元素的
初始化ArrayList的时候,可以指定初始化容量的大小,如果不指定,就会使用默认大小,为10
当添加一个新元素的时候,首先会检查容量是否足够添加这个元素,如果够就直接添加,如果不够就进行扩容,扩容为原数组容量的1.5倍
当在index处放置一个元素的时候,会将数组index处右边的元素全部右移
当在index处删除一个元素的时候,会将数组index处右边的元素全部左移
手写arraylist:import java.util.Arrays; public class ExtArrayList<E> { //ArrayList底层采用数组存放 private Object[] elementData; //默认数组容量 private static final int DEFAULT_CAPACITY = 10; //记录实际ArrayList大小 private int size; //默认初始化容量为10 public ExtArrayList() { this(DEFAULT_CAPACITY); } //ArryList指定数组初始的容量 public ExtArrayList(int initialCapacity) { if (initialCapacity < 0) { throw new IllegalArgumentException("初始化容量不能小于0"); } elementData = new Object[initialCapacity]; } public void add(E e) { //1.判断实际存放的数据容量是否大于elementData ensureCapacityInternal(size + 1); //2.使用下标进行赋值 elementData[size++] = e; } public void add(int index, E e) { rangeCheck(index); ensureCapacityInternal(size + 1); System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = e; size ++; } // int minCapacity 当前 size + 1 private void ensureCapacityInternal(int minCapacity) { if (size == elementData.length) { // //新数组容量大小 // int newCapacity = 2 * size; // Object[] newObjects = new Object[newCapacity]; //新旧数组复制 // for (int i = 0; i < elementData.length; i++) { // newObjects[i] = elementData[i]; // } // elementData = newObjects; //新旧数组复制 int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); //最小扩容容量;防止初始容量大小为1 if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } elementData = Arrays.copyOf(elementData, newCapacity); } } //使用下标获取数组元素 public Object get(int index) { return elementData[index]; } @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } public Object remove(int index) { rangeCheck(index); //1.使用下标查询该值是否存在 Object object = get(index); //计算删除元素后面的长度 int numMoved = size - index - 1; if (numMoved > 0) { //2.删除原理分析,将删除元素后面的所有元素往前移动一位 System.arraycopy(elementData, index + 1, elementData, index, numMoved); } //将最后一个元素变为空 elementData[--size] = null; return object; } // 删除相同元素 删除第一个 public boolean remove(E e) { for (int i = 0; i < elementData.length; i++) { Object value = elementData[i]; if (value.equals(e)) { remove(i); return true; } } return false; } //判断下标是否越界 private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException("越界啦!"); } public int getSize() { return size; } }
1.18 List、Map、Set的理解(LinkedList和ArrayList、Vector和ArrayList、HashMap和HashTable和HashSet区别与使用)
List特点:元素有放入顺序,元素可重复
Map特点:元素按键值对存储,无放入顺序
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
List接口有三个实现类:LinkedList,ArrayList,Vector
LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢
ArrayList和Vector的区别:ArrayList是非线程安全的,效率高;Vector是基于线程安全的,效率低
Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet
SortedSet接口有一个实现类:TreeSet(底层由平衡二叉树实现)
Query接口有一个实现类:LinkList
Map接口有三个实现类:HashMap,HashTable,LinkeHashMap
HashMap非线程安全,高效,支持null;HashTable线程安全,低效,不支持null
SortedMap有一个实现类:TreeMap
其实最主要的是,list是用来处理序列的,而set是用来处理集的。Map是知道的,存储的是键值对
set 一般无序不重复.map kv 结构 list 有序1.19 为什么重写了equals()也要重写hashCode()
1.20 Java字符串池(String Pool)深度解析
1.21 计算机网络知识
TCP/IP协议:https://blog.csdn.net/wuzhiwei549/article/details/105965493?utm_medium=distribute.pc_feed.none-task-blog-alirecmd-1.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-alirecmd-1.nonecase&request_id=2 安卓部分
2.1 安卓系统架构
2.2 安卓性能优化
2.3 APP启动优化
App没有启动过或App进程被killed, 系统中不存在该App进程。需要创建App进程, 加载相关资源, 启动Main Thread, 初始化首屏Activity等。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至首屏Activity完全启动。
2、热启动
热启动意味着你的App进程只是处于后台, 系统只是将其从后台带到前台, 展示给用户。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至activity渲染完毕。
3、温启动
介于冷启动和热启动之间, 一般来说在以下两种情况下发生:
用户back退出了App, 然后又启动. App进程可能还在运行, 但是activity需要重建
用户退出App后, 系统可能由于内存原因将App杀死, 进程和activity都需要重启
启动优化主要是针对冷启动. 热启动和温启动都相对较快。2.4 安卓界面绘制原理
2.5 安卓事件机制
见文章:https://segmentfault.com/a/11900000122277362.6 安卓app启动流程
见文章:https://www.cnblogs.com/net19880504/p/10931222.html2.7 recycleview原理
手写实现简单的recycleview:https://github.com/buder-cp/CustomView/tree/master/buder_DN_view/buderdn19202.8 设计模式
设计模式23种模式代码实现:https://quanke.gitbooks.io/design-pattern-java/content/2.9 handler机制
见文章:https://www.jianshu.com/p/592fb6bb69fa
处理消息的线程,其实是发送handler所持有的Looper所在的线程。
消息是如何插入到MessageQueue中:
我们之前说,所有handler.post和handler.sendMessage都会调用到Handler的sendMessageDelayed方法,方法如下:public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
答:App的运行、更新UI、AsyncTask、Glide、RxJava等
处理Handler消息,是在哪个线程?一定是创建Handler的线程么?
答:创建Handler所使用的Looper所在的线程
消息是如何插入到MessageQueue中的?
答: 是根据when在MessageQueue中升序排序的,when=开机到现在的毫秒数+延时毫秒数
当MessageQueue没有消息时,它的next方法是阻塞的,会导致App ANR么?
答:不会导致App的ANR,是Linux的pipe机制保证的,阻塞时,线程挂起;需要时,唤醒线程
子线程中可以使用Toast么?
答:可以使用,但是Toast的显示是基于Handler实现的,所以需要先创建Looper,然后调用Looper.loop。
Looper.loop()是死循环,可以停止么?
答:可以停止,Looper提供了quit和quitSafely方法
Handler内存泄露怎么解决?
答: 静态内部类+弱引用 、Handler的removeCallbacksAndMessages等方法移除MessageQueue中的消息
handler.postDelayed函数延时执行计时是否准确?
答:当上一个消息存在耗时任务的时候,会占用延时任务执行的时机,此时是不准确的。那么如何准确执行延时任务呢,可以开启一个HandlerThread为一个专门的唯一的延时消息服务。
解析:根据源码说原因
由于Loop.loop里面消息是串行取出并发给handler.dispatchMessage的,而postDelayed函数调用的时候执行时间就已经算好了,这里假设调用postDelayed的当前时间SystemClock.uptimeMillis为1s,那么算上delayMillis就是1s+1s=2s,也就是系统开机后第2s,它应该在系统时间的第2s就应该被执行了,但因为消息执行是串行执行的,上一个runnable 里面调用了Thread.sleep(3000),也就是说上一个任务执行需要3s,系统时间一下就到了第3S,那么轮到处理第二个延时runnable的时候,MessageQueue类的next方法再执行到`
138行if(now < msg.when)的时候,now是系统开机后第3秒,而此时msg.whe 是开机后第2秒,那么就会走到下面的else分支,就立刻return了该msg,然后由handler.dispatchMessage处理,执行到该runnable的run方法,此时Log打印的时间就是3150毫秒了.2.10 binder机制
2.11 Java 运算符
2.12 进制转换
2.13 java基本类型的范围
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=655352.14 Arouter 原理
组件化开发有什么优势?
组件化路由是什么,有什么用,说说实现方式?
使用**注解处理器**扫描所有模块的activity并生成对应的代码,通过单例执行生成类的方法,把所有的activity添加到单例的路由表中。
自己写的组件化2.15 热修复和插件化原理
2.16 横竖屏切换时 Activity 的生命周期
1.不设置 Activity 的 android:configChanges 时,切屏会重新调用各个生 命周期默认首先销毁当前 activity,然后重新加载。
2.设置 Activity
android:configChanges=“orientation|keyboardHidden|screenSize” 时,切
屏不会重新调用各个生命周期,只会执行 onConfigurationChanged 方法。2.17 如 何 退 出 Activity ? 如 何 安 全 退 出 已 调 用 多 个 Activity 的 Application?
2、记录打开的 Activity:
每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。
3、发送特定广播:
在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭 即可。
//给某个 activity 注册接受接受广播的意图
registerReceiver(receiver, filter)
// 如 果 过 接 受 到 的 是 关 闭 activity 的 广 播 activity finish()掉
4、递归退出
就 调 用 finish() 方 法 把 当 前 的
在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在 onActivityResult 中处理,递归关闭。
5、其实 也可以通过 intent 的 flag 来实现
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 激活一个新的 activity。
此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有 Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。2.18 请描述一下 Service 的生命周期
” 绑定模式: 当第一次调用 startService 的时候执行的方法依次为
onCreate()、onStartCommand(),当 Service 关闭的时候调用 onDestory 方 法。
绑定模式:第一次 bindService()的时候,执行的方法为 onCreate()、 onBind()解除绑定的时候会执行 onUnbind()、onDestory()。
上面的两种生命周期是在相对单纯的模式下的情形。我们在开发的过程中还
必须注意 Service 实例只会有一个,也就是说如果当前要启动的 Service 已经存
在了那么就不会再次创建该 Service 当然也不会调用 onCreate()方法。
一个 Service 可以被多个客户进行绑定,只有所有的绑定对象都执行了
onBind()方法后该 Service 才会销毁,不过如果有一个客户执行了 onStart() 方法,那么这个时候如果所有的 bind 客户都执行了 unBind()该 Service 也不会 销毁。
2.19 什么是IntentService?有何优点?
IntentService 是 Service 的子类,比普通的 Service 增加了额外的功能。 先看 Service 本身存在两个问题:
Service 不会专门启动一条单独的进程,Service 与它所在应用位于同一个进 程中;
Service 也不是专门一条新线程,因此不应该在 Service 中直接处理耗时的 任务;
二、IntentService 特征
会创建独立的 worker 线程来处理所有的 Intent 请求;
会创建独立的 worker 线程来处理 onHandleIntent() 方法实现的代码,无需 处理多线程问题;
所有请求处理完成后,IntentService 会自动停止,无需调用 stopSelf()方法 停止 Service;
为 Service 的 onBind()提供默认实现,返回 null;
为 Service 的 onStartCommand 提供默认实现,将请求 Intent 添加到队列 中;2.20 请介绍下 ContentProvider 是如何实现数据共享的
ContentProvider 是应用程序之间共享数据的接口。使用的时候首先自定义 一个类继承 ContentProvider,然后覆写 query 、 insert、 update、 delete 等
方法。因为其是四大组件之一因此必须在 AndroidManifest 文件中进行注册。
把自己的数据通过 uri 的形式共享出去,android 系 统 下 不 同 程 序 数 据 默 认 是 不 能 共 享 访 问 , 需 要 去 实 现 一 个 类 去 继 承 ContentProvider
public class PersonContentProvider extends ContentProvider{
public boolean onCreate(){
}
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])
}
第三方可以通过 ContentResolver 来访问该 Provider。2.21 为什么要用 ContentProvider?它和 sql 的实现上有什么差 别?
2.22 说说 ContentProvider、ContentResolver、ContentObserver 之间的关系
b. ContentResolver.notifyChange(uri)发出消息
c. ContentResolver 内容解析者,用于获取内容提供者提供的数据
d. ContentObserver 内容监听器,可以监听数据的改变状态
e. ContentResolver.registerContentObserver()监听消息。2.23 使用 contentProvider 获取本地所有的音频文件
数据库(sqlite 数据库),将文件的名称、大小等信息存储起来,从而完成多媒体 数据的维护工作;所以我们需要实现建立一个实体类。
可以根据 ContentResover 获取到一个 Cursor,然后根据这个游标,遍历所
有的歌曲的信息,设置给实 体 类 ,得到你想要的音频文件。因为是从本地读取数 据,所以需要添加权限<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>
2.24 ListView 如何实现分页加载
② 在滚动状态发生改变的方法中,有三种状态:
手指按下移动的状态:SCROLL_STATE_TOUCH_SCROLL: // 触摸滑动 惯性滚动(滑翔(flgin)状态):SCROLL_STATE_FLING: // 滑翔
静止状态: SCROLL_STATE_IDLE: // 静止
对不同的状态进行处理:
分批加载数据,只关心静止状态:关心最后一个可见的条目,如果最后一个 可见条目就是数据适配器( 集 合 )里的最后一个,此时可加载更多的数据。在每次加载的时候,计算出滚动的数量,当滚动的数量大于等于总数量的时候,可以提 示用户无更多数据了。2.25 如何在ScrollView 中如何嵌入 ListView
在 ScrollView 添加一个 ListView 会导致 listview 控件显示不全,通常只会显示一条,这是因为两个控件的滚动事件冲突导致。所以需要通过 listview 中的item 数量去计算 listview 的显示高度,从而使其完整展示,现阶段最好的处理的方式是: 自定义 ListView,重载 onMeasure()方法,设置 全部显示。2.26 Serializable 和 Parcelable 的 区别
1.Serializable 在序列化的时候会产生大量的临时变量,从而引起频繁的 GC。
2.Parcelable 不能使用在要将数据存储在磁盘上的情况。尽管 Serializable 效率低点,但在这种情况下,还是建议你用 Serializable 。
实现:
1.Serializable 的实现,只需要继承 Serializable 即可。这只是给对象打
了一个标记,系统会自动将其序列化。
2.Parcelabel 的实现,需要在类中添加一个静态成员变量 CREATOR,这 个变量需要继承 Parcelable.Creator 接口。2.27 如何避免 OOM 异常
(1)图片过大导致OOM
Android 中 用 bitmap 时 很 容 易 内 存 溢 出 , 比 如 报 如 下 错 误 : Java.lang.OutOfMemoryError : bitmap size exceeds VM budget。解决方法:方法 1: 等比例缩小图片,方法 2:对图片采用软引用,及时地进行 recyle()操作,方法 3:使用加载图片框架处理图片,如专业处理加载图片的 ImageLoader 图 片加载框架。
(2)界面切换导致OOM
一般情况下,开发中都会禁止横屏的。因为如果是来回切换话,activity 的 生命周期会重新销毁然后创建。
有时候我们会发现这样的问题,横竖屏切换 N 次后 OOM 了。
这种问题没有固定的解决方法,但是我们可以从以下几个方面下手分析。
1、看看页面布局当中有没有大的图片,比如背景图之类的。
去除 xml 中相关设置,改在程序中设置背景图(放在 onCreate()方法中):
在 Activity destory 时注意,drawable.setCallback(null); 防止 Activity 得 不到及时的释放。
2、跟上面方法相似,直接把 xml 配置文件加载成 view 再 放 到 一 个 容 器 里, 然 后 直 接 调 用 this.setContentView(View view);方法,避免 xml 的重复加载。
3、 在页面切换时尽可能少地重复使用一些代码
比如:重复调用数据库,反复使用某些对象等等…
(3)查询数据库没有关闭游标
程序中经常会进行查询数据库的操作,但是经常会有使用完毕 Cursor 后 没 有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会出现内存问题,这样就会给以后的测试和问题排 查带来困难和风险。
(4)构造Adapter 时,没有使用缓存的 convertView
在使用 ListView 的时候通常会使用 Adapter,那么我们应该尽可能的使用 ConvertView 。
为什么要使用convertView?
当 convertView 为空时,用 setTag()方法为 每个 View 绑定一个存放控件的ViewHolder 对象。当convertView 不为空,重复利用已经创建的 view 的时候,使用 getTag()方法获取绑定的 ViewHolder 对象,这样就避免了 findViewById 对控件的层层查询,而是快速定位到控件。
(5)Bitmap 对象不再使用时调用recycle()释放内存
有时我们会手工的操作 Bitmap 对象,如果一个 Bitmap 对象比较占内存,当它不再被使用的时候,可以调用 Bitmap.recycle()方 法回收此 对象的像素 所占 用的内存,但这不是必须的,视情况而定。
(6)其他
Android 应用程序中最典型的需要注意释放资源的情况是在Activity 的生命周期中,在 onPause()、onStop() 、 onDestroy()方法 中需 要适当的释 放资 源的情况。使用广播没有注销也会产生 OOM。2.28 ANR 是什么?怎样避免和解决 ANR
Activity 5 秒 broadcast10 秒
耗时的操作 worker thread 里面完成, handler message… AsynTask , intentservice.等…
ANR:Application Not Responding,即应用无响应
ANR 一 般 有 三 种 类 型 :
1:KeyDispatchTimeout(5 seconds) –主要类型按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds)BroadcastReceiver 在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) –小概率类型Service 在特定的时间内无法处理完成
超时的原因一般有两种:
(1)当前的事件没有机会得到处理(UI 线程正在处理前一个事件没有及时完成或 者 looper 被某种原因阻塞住)
(2)当前的事件正在处理,但没有及时完成
UI 线程尽量只做跟 UI 相关的工作,耗时的工作(数据库操作,I/O,连接网络或者其他可能阻碍 UI 线程的操作)放入单独的线程处理,尽量用 Handler 来处 理 UI thread 和 thread 之间的交互。
查找 ANR 的方式: 1. 导出/data/data/anr/traces.txt,找出函数和 调用过程, 分析代码 2. 通过性能 LOG 人肉查找2.29 Android 线程间通信有哪几种方式
文件,数据库;
Handler;
Java 里的 wait(),notify(),notifyAll()2.30 android 应用对内存是如何限制的?我们应该如何合 理使用内 存?
•Android 每一个应用的堆内存大小有限
•通常的情况为 16M-48M
•通过 ActivityManager 的 getMemoryClass()来查询可用堆内存限制
•3.0(HoneyComb)以上的版本可以通过 largeHeap=“true”来申请更多 的堆内存
•NexueHeap 512
•如果试图申请的内存大于当前余下的堆内存就会引发 OutOfMemoryError()
•应用程序由于各方面的限制,需要注意减少内存占用,避免出现内存泄漏。2.31 如何合理使用内存?
2、少 使用 静态 变量 ,因为 系统 将静 态变 量的优 先级 设定 的很 高, 会最后 回
收。所以可能因为静态变量导致该回收的没有回收。而回收了不该回收的内 存。
3、注意大图片的缩放,如果载入的图片很大,要先经过自己程序的处理,
降低分辨率等。最好设置多种分辨率格式的图片,以减少内存消耗。
4、动态注册监听,把一些只有显示的时候才使用到的监听放进程序内部, 而不是放在 manifesat 中去。
5、减少使用动画,或者适当减少动画的帧数。
6 、 注意 自己 的 程 序 逻辑, 在该 关闭 自己 程序的 控件 的时 候, 主动 关闭, 不 要交给系统去决定。(这个要自己把握好,也不是说都自己搞定,只有那些 自己确定需要关闭的对象,自己将其关闭。)2.32 简述android 应用程序结构是哪些?
gen 目录是 1.5 版本新增的目录,用来保存 ADT 自动生成的 java 文件,例 如 R.java 或 AIDL 文件
注 意 :R.java 文件(非常重要)
a) R.java 文件是 ADT 自动生成的文件,包含对 drawable、layout 和 values目录内的资源的引用指针,Android 程序能够直接通过 R 类引用目录中的资源
b) R.java 文件不能手工修改,如果向资源目录中增加或删除了资源文件,则需 要在工程名称上右击,选择 Refresh 来更新 R.java 文件中的代码
c) R 类包含的几个内部类,分别与资源类型相对应,资源 ID 便保存在这些内部类中,例如子类 drawable 表示图像资源,内部的静态变量 icon 表示资源 名称,其资源 ID 为 0x7f020000 。一般情况下,资源名称与资源文件名相同android.jar 文件是 Android 程序所能引用的函数库文件,Android 通过平 台所支持 API 都包含在这个文件中assets 目录用来存放原始格式的文件,例如音频文件、视频文件等二进制格式文件。此目录中的资源不能被 R.java 文件索引。,所以只能以资截流的形式 读取。一般情况下为空layout 目录用来存放我们为每个界面写的布局文件Strings.xml 文件是程序中的一些字符串的引用
AndroidManifest.xml 是 XML 格式的 Android 程序声明文件,包含了Android 系统运行 Android 程序前所必须掌握的重要信息,这些信息包含应用程序名称、图标、包名称、模块组成、授权和 SDK 最低版本等,而且每个 Android 程序必须在根目录下包含一个 AndroidManifest.xml 文件
注:AndroidMainfest.xml 文件:
xmlns:android、package、android:versionCode 和 android:versionName 共 4 个属性
越大说明版本越新,但仅在程序内部使用,并不提供给应用程序的使用者
声明 Android 程序中最重要的四个组成部分,包括 Activity、Service、
BroadcastReceiver 和 ContentProvider,所定义的属性将影响所有组成部分
default.properties 文件记录 Android 工程的相关设置,该文件不能手动修 改,需右键单击工程名称,选择“Properties”进行修改2.33 多线程间通信和多进程之间通信有什么不同,分别怎么实现?
能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
) 有名管道 (namedpipe) : 有名管道也是半双工的通信方式,但是它允许 无亲缘关系进程间的通信。
) 信 号 量 ( semophore ) : 信号量是一个计数器,可以用来控制多个进程对 共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其
他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的 同步手段。
) 消 息 队 列 ( messagequeue ) : 消息队列是由消息的链表,存放在内核中
并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无 格式字节流以及缓冲区大小受限等缺点。
) 信号 (sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个 事件已经发生。
)共 享 内 存 ( shared memory ) :共享内存就是映射一段能被其他进程所访问 的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最
快 的 IPC 方 式, 它 是 针 对其他 进程 间 通信 方 式 运行 效 率低 而 专门 设 计 的。它
往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
)套接字(socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同 的是,它可用于不同及其间的进程通信。
)锁机制:包括互斥锁、条件变量、读写锁
*互斥锁提供了以排他方式防止数据结构被并发修改的方法。
信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于 数据交换的通信机制。2.34 什么是 AIDL 以及如何使用
②使用 aidl 可以帮助我们发布以及调用远程服务,实现跨进程通信。 ③将服务的 aidl 放到对应的 src 目录,工程的 gen 目录会生成相应的接口类
我们通过 bindService(Intent,ServiceConnect,int)方法绑定远程服务, 在 bindService 中有一个 ServiceConnec 接口, 我们需要覆写该类的
onServiceConnected(ComponentName,IBinder) 方法,这个方 法的第二个参
数 IBinder 对象其实就是已经在 aidl 中定义的接口,因此我们可以将 IBinder 对象强制转换为 aidl 中的接口类。
我们通过 IBinder 获取到的对象(也就是 aidl 文件生成的接口)其实是系统 产生的代理对象,该代理对象既可以跟我们的进程通信,又可以跟远程进程通信, 作 为一个中间的角色实现了进程间通信。2.35 安卓屏幕适配方案
适配框架:https://github.com/JessYanCoding/AndroidAutoSize/blob/master/README-zh.md2.36 Git
2.37 Linux常用命令
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算