Android面试准备

一、简历准备

1、个人技能

(1)自定义控件、UI设计、常用动画特效
    1. 自定义控件

①为什么要自定义控件?

Android本身提供了很多控件,但是这些控件并不能满足我们所有的要求,现在用户的要求越来越高,这就要求我们做出的软件除了功能要齐全外,还要给用户比较炫比较人性化的体验,这个时候就需要我们自定义控件来提高用户体验。
现在用户体验是炒得比较火的一个概念,各大网站各个软件都在说提高用户体验。
Android中的控件都是继承自View类,通过重写onDraw方法来绘制我们所需的控件。

②如何实现自定义控件?

实现自定义控件的两种方式:
第一是继承已有控件,通过重写相关方法来实现我们的需求
第二是继承View类或者ViewGroup类来绘制我们需要的控件
注:一般来讲,通过继承已有的控件来实现自定义控件简单一点,开发中常用继承已有控件来实现自定义控件。

③ListView:

a、ListView的作用是什么?
显示数据
b、ListView如何用?
首先要给ListView设置一个适配器Adapter,把要显示的数据交给适配器Adapter去处理,
另外ListView的getView方法每被调用一次显示一个条目,都伴随着一个旧的条目被移除,故为了优化ListView,可以在getView()方法中重用旧条目convertView
还有ListView的getView方法中每执行一次findViewById方法时,都会加载相应布局的树状结构,再遍历该树状结构找到指定id,当该布局的树状结构很复杂时,每次都查找id会比较麻烦,所以为了优化我们可以提供一个ViewHolder类,用来记录布局中的所有控件,这样布局中的控件id只需查找一次,再用时,直接在ViewHolder类里面取最后用ListView显示大数据时,还需要进行分批加载或分页显示处理.

    1. 动画特效:

①动画的分类:

安卓中的动画分为两种,一种是帧动画(Frame),一种是渐变动画(Tweened) , 渐变动画又分为四种动画类型,Alpha、Scale、Translate和Rotate

(2)网络数据传输,熟悉多线程、Socket网络编程、熟悉TCP、UDP、HTTP等协议
    1. 网络编程概述:

①网络模型:

OSI模型
应用层
表示层
会话层
传输层
网络层
数据连接层
物理层
TCP/IP模型
应用层
传输层
网际层
主机至网络层

②网络通讯要素

IP地址
端口号
传输协议

③网络通讯前提:

找到对方IP
数据要发送到指定端口。为了标示不同的应用程序,所以给这些网络应用程序都用数字进行标示这个表示就叫端口
定义通信规则。这个规则称为通信协议,国际组织定义了通用协议TCP/IP

    1. Android网络应用的概述:
      Android完全支持JDK本身的TCP、UDP网络通信API,可以使用Socket、ServerSocket来建立基于TCP/IP协议的网络通信;
      也可以使用DatagramSocket/Datagrampacket来建立基于UDP协议的网络通信。
      同时Android还支持JDK提供的URL、URLConnection等网络通信的API。
    1. TCP和UDP的区别:

①UDP协议:

面向无连接
每个数据报的大小在限制在64k内
因为是面向无连接,所以是不可靠协议
不需要建立连接,速度快

②TCP协议:

必须建立连接,形成传输数据的通道
在连接中可进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
注:三次握手:
第一次:我问你:在么?
第二次:你回答:在。
第三次:我反馈:哦,我知道你在。

    1. Socket:
      **Socket就是为网络服务提供的一种机制
      **通信的两端都有Socket
      **网络通信其实就是Socket间的通信
      **数据在两个Socket间通过IO传输
      **玩Socket主要就是记住流程,代码查文档就行
    1. UDP(User Datagram Protocol):用户数据协议

①UDP概述:

需要DatagramSocket与DatagramPacket对象来实现UDP协议传输数据
UDP协议是一种面向无连接的协议。面向无连接的协议指的是正式通信前不必与对方先建立连接,不管对方连接状态就直接发送数据。

②UDP协议开发步骤:

**发送端:
建立DatagramSocket服务;
提供数据,并将数据封装到字节数组中;
创建DatagramPacket数据包,并把数据封装到包中,同时指定接收端IP和接收端口
通过Socket服务,利用send方法将数据包发送出去;
关闭DatagramSocket和DatagramPacket服务。
**接收端:
建立DatagramSocket服务,并监听一个端口;
定义一个字节数组和一个数据包,同时将数组封装进数据包;
通过DatagramPacket的receive方法,将接收的数据存入定义好的数据包;
通过DatagramPacke关闭的方法,获取发送数据包中的信息;
关闭DatagramSocket和DatagramPacket服务。

③UDP协议的Demo(必须掌握):

****发送端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

class UDPSend {
    public static void main(String[] args) throws Exception {
        DatagramSocket ds = new DatagramSocket();
        byte[] buf = "这是UDP发送端".getBytes();
        DatagramPacket dp = new DatagramPacket(buf, buf.length,
                InetAddress.getByName("192.168.1.253"), 10000);
        ds.send(dp);
        ds.close();
    }
}

****接收端

import java.net.DatagramPacket;
import java.net.DatagramSocket;

class UDPRece {
    public static void main(String[] args) throws Exception {
        DatagramSocket ds = new DatagramSocket(10000);
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);
        ds.receive(dp);// 将发送端发送的数据包接收到接收端的数据包中
        String ip = dp.getAddress().getHostAddress();// 获取发送端的ip
        String data = new String(dp.getData(), 0, dp.getLength());// 获取数据
        int port = dp.getPort();// 获取发送端的端口号
        System.out.print(ip + ":" + data + ":" + port);
        ds.close();
    }
}                   

注:协议的概念和作用:
什么是协议? 网络通信的一种规则
协议的作用? 保证通信两端实现网络通信

    1. TCP/IP协议:Socket和ServerSocket

①基于TCP协议的网络通信概述:

TCP/IP通信协议是一种必须建立连接的可靠的网络通信协议。它在通信两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。
网络虚拟链路一旦建立,两端的程序就可以进行通信。

②TCP/IP协议开发步骤:

**客户端:
建立Socket服务,并指定要连接的主机和端口;
获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端;
获取Socket流中的输出流InputStream,获取服务端的反馈信息;
关闭资源。
**服务端:
建立ServerSocket服务,并监听一个端口;
通过ServerSocket服务的accept方法,获取Socket服务对象;
使用客户端对象的读取流获取客户端发送过来的数据;
通过客户端对象的写入流反馈信息给客户端;
关闭资源

③TCP/IP协议的一个Demo(必须要掌握!):

客户端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

class TCPClient {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("192.168.1.253", 10000);
        OutputStream os = s.getOutputStream();
        os.write("这是TCP发送的数据".getBytes());
        s.close();
    }
}

服务端:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(10000);
        Socket s = ss.accept();

        String ip = s.getInetAddress().getHostAddress();
        System.out.print(ip);

        InputStream is = s.getInputStream();
        byte[] buf = new byte[1024];
        int len = is.read(buf);
        System.out.print(new String(buf, 0, len));
        s.close();
        ss.close();
    }
}
    1. HTTP协议:

    a、HTTP是Hyper Text Transfer Protocol的缩写
    b、是由W3C制定和维护的。目前版本为1.0和1.1
    c、是开发web的基石,非常地重要
    d、 1.0版本:是无状态的协议,即一次连接只响应一次请求,响应完了就关闭此次连接,要想再访问须重新建立连接。而连接都是比较耗资源的。
    1.1版本:是有状态的协议。即可以在一次网络连接基础上发出多次请求和得到多次的响应。
    当距离上次请求时间过长时,服务器会自动断掉连接,这就是超时机制。

①HTTP协议的组成:
请求部分:

请求行:GET / HTTP/1.1 包含:请求方式GET 请求的资源路径:/ 协议版本号:HTTP/1.1
请求方式。常用的有GET、POST
GET方式:默认方式。直接输入的网址。
表单数据出现在请求行中。url?username=abc&password=123
特点:不安全;有长度限制:<1k
POST方式:可以通过表单form method="post"设置
表单数据会出现在正文中。
特点:安全;没有长度限制
请求消息头:
请求正文:第一个空行之后的全部都是请求正文

响应部分:

响应行:HTTP/1.1 200 OK 包含:协议版本号:HTTP/1.1 响应码:200 描述:OK
响应码:(实际用到的30个左右,其他都是W3C保留的)
描述:对响应码的描述
常用响应码:
200:一切正常
302/307:请求的资源路径变更了
304:资源没有被修改过
404:资源不存在,找不到资源
500:服务器程序有错
响应消息头:
响应正文:第一个空行之后的全部都是响应正文,浏览器显示的就是正文中的内容

    1. 网络通信中加入多线程:

①TCP/IP协议:

实际应用中,服务端需要不断的读取客户端数据和写入数据到客户端;而客户端也需要不断的读取服务端数据和写入数据到服务端。
当使用传统的BufferedReader的readLine()方法读取数据时,由于该方法是阻塞式方法,故当该方法成功返回之前,线程被阻塞,程序无法继续执行。居于此,服务器应该为每个Socket单独开启一条线程,每个线程负责与一个客户端进行通信。
客户端应该包含两条线程,一条负责生产主界面、相应用户动作并将用户输入的数据写入到Socket对应的输出流中,另一条负责读取Socket对应输入流中从服务器端发送过来的数据,并负责将这些数据在主界面上显示。
使用NIO实现非阻塞Socket通信(JDK 1.4以后开始):使用NIO API可以让服务器端使用一个或者有限个线程来同时处理连接到服务端的所有客户端,如多人聊天室
使用AIO(Asynchronous IO)实现非阻塞通信(JDK 1.7开始):通过支持异步Channel来实现

②多线程应用:

a、多线程的作用:提高效率
b、多线程的应用:
多线程下载:
创建URL对象
获取指定URL对象所指向的资源的大小(getConnectionLength())
在本地磁盘上创建一个与网络资源大小相同的空文件:RandomAccessFile.setLength()
计算每条线程应该下载网络资源的哪个部分(从哪个字节开始到哪个字节结束)
依次创建、启动多线程来下载网络资源的指定部分
//执行如下代码设置请求头,确定指定线程下载的部分;如果不设置该头,则每个线程都从头下载到末尾
HttpURLConnection.setRequestProperty("Range","bytes="+start+"-"+end);
多线程断点续传下载:开始下载时,判断是否是新的下载任务
如果是,从头开始下载
如果不是,找到上次下载完成多少,继续下载
下载过程中记录每条线程的下载进度,同时下载多少就写多少到本地,并且每次向文件中写入数据之后,在数据库中更新下载进度下载完成之后删除数据库中下载记录

    1. 网络通信中的URL编程:

①URL概述:

URL(Uniform Resource Locator)对象代表统一资源定位器,是指向网络资源的指针。网络资源可以是简单的文件或者目录,也可以是复杂的对象的引用,例如对数据库或搜索引擎的查询。

②URL组成:由协议名、主机、端口和资源路径组成。如Http://localhost:8080/BookShop/index.jsp
③URL的应用:

使用URL访问网络资源:
使用URLConnection提交请求:
通过URL.openConnection()创建URLConnection对象
设置URLConnection对象的参数和普通请求属性
发送GET或者POST请求
使用HttpURLConnection访问网络资源:

(3)Handler消息传递机制和Android下的消息推送机制:
    1. Handler消息传递机制:

①Handler概述:

Handler是界面刷新机制
Handler是用来解决Android应用多线程间通信问题,主线程和子线程之间通信问题
Android系统不允许Activity新启动的线程访问该Activity里面的界面组件。这就导致新启动的线程无法动态改变
该界面组件的属性值。即主线程创建View,但无法获取数据;新线程有数据,但无法修改View。Handler消息传递机制就可以解决此类问题。

②Handler的作用:

a、Handler用在一个线程中,Handler的作用就是实现异步操作;
b、Handler用在不同线程中,Handler的作用就是实现异步操作和实现线程间通信。

③Handler和Looper的关系:

a、Handler主要是用来发送和处理消息,但是发送了消息后,消息是怎么传递的呢?
这就是Looper的作用了,每个Handler内部都会封装一个Looper对象,如果在创建Handler的时候不指定Looper对象,系统就会默认将当前线程的Looper绑定到Handler上,Looper对象中维护者一个消息队列,Handler发送的消息都会存储到这个消息队列中,Looper不断的遍历这个消息队列,取出消息,交给handleMessage方法处理,Looper属于哪个线程,hadleMessage方法就会在那个线程中执行。
b、Looper对象的作用:Looper负责管理线程的消息队列和消息循环
**主线程的Looper对象:当在主线程中使用Handler的时候,不用指定Looper,因为在主线程开启的时候,就已经调用了Looper.loop()方法开始轮询了。通过Handler.getLooper()可获取当前主线程的Looper对象
主线程可通过Looper对象给子线程发送消息
**子线程的Looper对象:在子线程中使用Handler的时候,通过调用Looper的prepare方法创建存储Looper对象,还得调用Looper.loop()方法开启轮询。
一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程、跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。
注:Android中除了进度条,其他View在创建该View的线程中修改。

④Handler如何使用:

Handler的使用需要四个对象配合使用:Handler、Looper、Message和Thread

⑤Handler和AsyncTask的区别:

a、相同点:AsyncTask和Handler都能通过主线程和子线程之间的通信更新主界面
b、不同点:Handler比较麻烦,而AsyncTask使任务更加方便,而且AsyncTask过程可控;
对于多个后台任务时,使用Handler代码结构清晰简单;而使用多个AsyncTask时容易发生异常。

    1. Android下的消息推送机制:

①消息推送机制概述:

当我们开发和服务器交互的应用时,基本上都需要获取服务端的数据,这就需要消息推送机制来实现。

②获取服务器上不定时更新的信息的两种方式:

第一种是客户端使用Pull(拉)的方式,客户端每隔一段时间去服务端获取信息,看是否有更新的信息,有就获取
第二种是服务端使用Push(推)的方式,服务端更新数据了,就把更新的数据Push到客户端
注:虽然Pull和Push方式都能实现获取服务端更新的数据的功能,但明显的Push方式比Pull更节省用户的流量和电量

③消息推送解决方案:

****轮循Pull : 应用程序阶段性的与服务器进行连接并查询是否有新消息
缺陷:要考虑轮询的频率,如果太慢可能导致某些消息的延迟,如果太快,则会大量消耗网络带宽和电池
****SMS Push: 通过拦截SMS消息并且解析消息内容来了解服务器的意图
缺陷:成本相对比较高,你很难找到免费的短消息发送网关
****持久连接Push : 缺陷:很难在手机上实现一个可靠的服务,并且非常消耗手机的电池

④消息推送服务:

****C2DM(Cloud to Device Messaging)服务:
C2DM是Google提供的消息推送服务,是一个简单的、轻量级的机制,允许服务器可以通知移动应用程序直接与服务器进行通信以便于从服务器获取应用程序更新和用户数据。
C2DM服务负责处理诸如消息排队等事务并向运行于目标设备上的应用程序分发这些消息。
C2DM服务的问题:C2DM内置于Android的2.2系统上,无法兼容老的1.6到2.1系统
C2DM需要依赖于Google官方提供的C2DM服务器,由于国内的网络环境,这个服务经常不可用,如果想要很好的使用,我们的App Server必须也在国外,这个恐怕不是每个开发者都能够实现的
****MQTT协议实现Android推送:MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案
wmqtt.jar 是IBM提供的MQTT协议的实现
****RSMB实现推送:Really Small Message Broker (RSMB) ,他是一个简单的MQTT代理,同样由IBM提供
****XMPP协议实现Android推送:
Google官方的C2DM服务器底层也是采用XMPP协议进行的封装
XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。
这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息
androidpn是一个基于XMPP协议的java开源Android push notification实现
注:XMPP协议实现Android推送的最大优势就是简单,我们不需要象C2DM那样依赖操作系统版本,也不会担心某一天Google服务器不可用。
利用XMPP协议我们还可以进一步的对协议进行扩展,实现更为完善的功能。采用这个方案,我们目前只能发送文字消息,不过对于推送来说一般足够了,因为我们不能指望通过推送得到所有的数据

    1. 多线程间通信

①进程和线程以及多线程的概念:

进程:正在进行的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元
线程:进程内部的一条执行路径或者一个控制单元
注:两者的区别:一个进程至少有一个线程
进程在执行过程中拥有独立的内存单元,而多个线程共享一个内存单元
多线程:一个进程中有多个线程,称为多线程

②多线程的优势和弊端:

优势:解决了多部分同时运行的问题,提高效率
弊端:线程太多会导致效率的降低,因为线程的执行依靠的是CPU的来回切换

③实现多线程的方法:

实现多线程可以通过继承Thread类和实现Runnable接口
a、继承Thread
定义一个类继承Thread类
复写Thread类中的public void run()方法,将线程的任务代码封装到run方法中
直接创建Thread的子类对象,创建线程
调用start()方法,开启线程(调用线程的任务run方法)
b、实现Runnable接口;
定义一个类,实现Runnable接口;
覆盖接口的public void run()的方法,将线程的任务代码封装到run方法中;
创建Runnable接口的子类对象
将Runnabl接口的子类对象作为参数传递给Thread类的构造函数,创建Thread类对象
(原因:线程的任务都封装在Runnable接口子类对象的run方法中。所以要在线程对象创建时就必须明确要运行的任务)。调用start()方法,启动线程。
注:两种方法区别:
(1)实现Runnable接口避免了单继承的局限性
(2)继承Thread类线程代码存放在Thread子类的run方法中
实现Runnable接口线程代码存放在接口的子类的run方法中;
在定义线程时,建议使用实现Runnable接口,因为几乎所有多线程都可以使用这种方式实现

④线程的几种状态:

新建:new一个Thread对象或者其子类对象就是创建一个线程,当一个线程对象被创建,但是没有开启,这个时候, 只是为线程对象开辟了内存空间和初始化数据。
就绪:新建的对象调用start方法,就开启了线程,线程就到了就绪状态。在这个状态的线程对象,具有执行资格,没有CPU执行权。
运行:当线程对象获取到了CPU的资源。在这个状态的线程对象,既有执行资格,也有执行权。
冻结:运行过程中的线程由于某些原因(比如wait,sleep),释放了执行资格和执行权。
当然,他们可以回到运行状态。只不过不是直接回到运行状态,而是先回到就绪状态。
死亡:当线程对象调用的run()方法结束,或者直接调用stop()方法,就让线程对象死亡,线程对象在内存中变成了垃圾。

⑤多线程安全问题:

a、原因:当程序的多条语句在操作线程的共享数据时(如买票例子中的票就是共享资源),由于线程的随机性导致一个线程执行多条语句时,执行了一部分还没执行完,另一个线程抢夺到cpu执行权参与进来执行,
此时就导致共享数据发生错误。比如买票例子中打印重票和错票的情况。
b、解决方法:对多条操作共享数据的语句进行同步,一个线程在执行过程中其他线程不可以参与进来

⑥Java中多线程同步:

a、同步的作用:同步是用来解决多线程的安全问题的,在多线程中,同步能控制对共享数据的访问。
如果没有同步,当一个线程在修改一个共享数据时,而另外一个线程正在使用或者更新同一个共享数据,这样容易导致程序出现错误的结果
b、同步的前提:必须保证有两个以上线程
必须是多个线程使用同一个锁,即多条语句在操作线程共享数据
必须保证同步中只有一个线程在运行
c、同步的好处和弊端
好处:同步解决了多线程的安全问题
弊端:多线程都需要判断锁,比较消耗资源
d、同步的两种表现形式:
同步代码块:可以指定需要获取哪个对象的同步锁,使用synchronized的代码块同样需要锁,但他的锁可以是任意对象考虑到安全问题,一般还是使用同一个对象,相对来说效率较高。
注意:**虽然同步代码块的锁可以使任何对象,但是在进行多线程通信使用同步代码快时,必须保证同步代码快的锁的对象唯一,否则会报错。
**同步函数的锁是this,也要保证同步函数的锁的对象和调用wait、notify和notifyAll的对象是同一个对象,也就是都是this锁代表的对象。
格式:
synchronized(对象){
需同步的代码;
}
同步函数
同步方法是指进入该方法时需要获取this对象的同步锁,在方法上使用synchronized关键字,使用this对象作为锁,也就是使用了当前对象,因为锁住了方法,所以相对于代码块来说效率相对较低。
注:静态同步函数的锁是该方法所在的类的字节码文件对象,即类名.class文件
格式:
修饰词 synchronized 返回值类型 函数名(参数列表){
需同步的代码;
}

⑦死锁

两个线程对两个同步对象具有循环依赖时,就会发生死锁。即同步嵌套同步,而锁却不同。

⑧为什么要线程间通信:

多线程并发执行的时候, 如果需要指定线程等待或者唤醒其他线程, 那么就需要线程间通信。比如生产者消费者的问题,生产一个消费一个,生产的时候需要负责消费的进程等待,生产一个后完成后需要唤醒负责消费的线程,同时让自己处于等待,消费的时候负责消费的线程被唤醒,消费完生产的产品后又将等待的生产线程唤醒,然后使自己线程处于等待。这样来回通信,以达到生产一个消费一个的目的

⑨线程间怎么通信

在同步代码块中, 使用锁对象的wait()方法可以让当前线程等待, 直到有其他线程唤醒为止.
使用锁对象的notify()方法可以唤醒一个等待的线程,或者notifyAll唤醒所有等待的线程.
多线程间通信用sleep很难实现,睡眠时间很难把握。

⑩Android开发中线程间通信应用案例:

a、Handler
b、Intent
注:进程间通信案例:服务、广播接收者、内容提供者等

(4)Android下的XML、JSON解析:
    1. XML的解析和生成:

解析XML的概述:常见的XML解析方式有三种,DOM、SAX和Pull
Android SDK中已经集成了Pull解析器,无需添加任何jar文件,故Android系统中推荐使用Pull解析XML
Pull解析器运行方式与SAX类似,提供各种事件的判断

①为什么要解析XML:

解析XML就是把XML文件里面各标签的属性、文本解析出来封装到javabean中,解析XML的关键就是如何拿到XML文件里面的元素的属性和文本

②解析XML的步骤:

a、获得解析器:XmlPullParser parser = Xml.newPullParser();
b、设置输入流以及编码,指定解析的是哪个输入流里面的XML文件
//去掉getClassLoader()则文件名前面加”/”,否则报错

InputStream in = PersonServiceTest.class.getClassLoader().getResourceAsStream("persons.xml");
parser.setInput(in, "UTF-8");

c、通过解析器XmlPullParser定义的常量了方法来解析XML文件
XmlPullParser事件类型常量:START_DOCUMENT、END_DOCUMENT 、START_TAG 、END_TAG 、TEXT
方法:
getEventType():获取事件的类型
next():往下解析
getName():获取标签的名字
getAttributeValue(int index):根据索引获取标签的属性,索引从0开始
getText():获取文本内容
nextText():获取下一个文本内容

③为什么要生成XML?

将javabean对象写入XML文件保存起来,所以生成XML文件的关键就是如何把javabean对象的属性数据生成XML文件的元素标签保存起来

④使用XmlSerializer生成XML文件的步骤:

a、获取序列化对象:XmlSerializer serializer = Xml.newSerializer();
b、设置序列化对象的输出流和编码,指定生成到哪个输出流里面的XML文件

FileOutputStream fos = new FileOutputStream("/mnt/sdcard/persons.xml");
serializer.setOutput(out,”UTF-8”);

c、通过序列化的各种方法将对象生成XML文件的各种元素标签属性
startDocument:开始XML文档
startTag:开始标签
attribute:设置标签的属性
text:设置标签的文本
endTag:结束标签
endDocument:结束XML文档

    1. JSON解析:

JSON文件就相当于是一个数组

解析JSON文件就相当于遍历存储JSON对象的JSONArray,获取每个JSONObject的数据,并封装到javabean中

①JSON的优缺点:

优点:作为数据传输格式,跟XML类似,但是比XML更加轻巧
由于JSON是JavaScript的原生格式,所以JSON不需要包含特定内容的首部信息
缺点:语法过于严谨
代码可读性差
其eval函数存在风险

(5)JNI调用:
    1. JNI概念:

什么是JNI?
JNI是Java Native Interface的缩写,即Java本地接口
JNI是一个协议,是用来沟通Java代码和C/C++代码的协议,是Java和C/C++之间的桥梁
通过JNI协议,Java可以调用外部的C/C++中的定义好的函数库;外部的C/C++也可以调用Java中封装好的类和方法

    1. 为什么用JNI:

①实际开发中的驱动都是用C开发,Java通过JNI就可以调用C开发好的驱动,从而扩展Java虚拟机的能力
比如Android系统的wifi-hostpot就是用C开发,Java通过JNI调用的

②提高效率,在高效率的数学运算、游戏的实时渲染、音频视频的编解码上,是C编写的,Java可通过JNI来调用C编写好的高效率的代码

③代码复用,Java实在2000年左右才逐渐发展起来的,而C语言七十年代就出现了,C中有很多非常好非常棒的函数库的封装,比如C中关于文件压缩(7-zip 纯C编写的 效率非常高)、人脸识别技术,我们Java不需要编写了,直接拿来调用就好
注:为什么C编写的代码效率高:C编写的代码不需要通过Java虚拟机编译,系统直接就认识直接就能用。

    1. 如何用JNI:

①C/C++基础:

指针:指针就是地址,地址就是指针
地址:内存单元的编号
指针变量:存放地址的变量
指针的重要性:
a、可直接访问硬件
b、快速传递数据
c、返回一个以上的值
d、表示复杂的数据结构
e、方便处理字符串
f、有助于理解面向对象

②JNI流程:

a、创建一个Android工程
b、在Java代码中声明一个本地方法,用javah工具生成头文件
c、在该Android工程中创建jni目录,引入头文件,根据头文件实现c代码,参考NDK工具中的jni.h文件,其中的结构体JNIEnv*对象和jobject对象很重要,在C代码中的方法必须传入这两个对象
d、在jni目录中创建并编写Android.mk文件
e、Ndk交叉编译生成动态库,即生成手机可执行的二进制文件(.so文件)
f、Java代码load 动态库.调用native代码:System.loadLibrary("Hello");//Hello为jni目录C/C++代码的.c文件

③NDK(native develop kits):

a、为什么需要NDK工具:在安卓开发中,因为底层都是C,且C程序不需要虚拟机编译底层就能读懂,故C效率比java快,故java需要调用C中代码。
而java不能直接调用C中代码,而是调用C代码的二进制文件,C代码里封装了C中丰富的函数。
Java想要调用C代码的可执行的二进制文件需经过以下两步骤:
编译:
将C源代码编译成不可执行的二进制文件;
该二进制文件在windows系统下是.obj文件
在Linux系统下是.o文件
链接:将编译好的二进制文件根据当前的操作系统系统链接成可执行的二进制文件,在链接过程中加入了必需的函数库
该二进制文件在windows系统下是.exe文件
在linux系统下是.so文件
b、交叉编译:Google提供了用C编写的NDK工具,该工具的ndk-build可实现在电脑上(windows操作系统,x86的CPU)
编译出可在手机(linux操作系统,arm的CPU)上执行的二进制文件。此过程就是交叉编译过程。
NDK工具需要运行在linux系统环境下,而cygwin是windows系统下模拟linux系统的一个工具,故安装NDK之前需安装cygwin软件。

(6)SQLite、MySql等数据库的CRUD及SharedPreferences的数据持久化
    1. SQLite:

①SQLite概述:

Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型
SQLite是手机自带的数据库,每一个数据库就是一个XML文件,每一个XML文件有一张或多张表

②创建SQLite数据库步骤:

a、定义类继承SQLiteOpenHelper
SQLiteOpenHelper是用来打开数据库的一个工具,其中有创建onCreate()数据库和升级upGrade()数据库方法,在获取数据库连接时,这些方法会自动执行,使用手机自带的SQLite数据库必须创建一个SQLiteOpenHelper子类,实现其onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int)方法,如果数据库不存在则创建,存在则检查数据库版本是不是最新,不是最新则升级数据库版本,维护其保持一个最佳的状态
b、获取数据库SQLiteDatabase对象
SQLiteOpenHelper. getWritableDatabase():获取写数据库,当可写时可获取读数据库
SQLiteOpenHelper. getReadableDatabase():获取读数据库
c、执行数据库增删改查操作
执行增删改操作,无返回结果集:SQLiteDatabase.execSQL(String sql,Object[] params);
执行查询操作:返回Cursor结果集SQLiteDatabase.rawQuery(String sql,String[] params);
或者执行CRUD操作:
SQLiteDatabase.insert();
SQLiteDatabase.update();
SQLiteDatabase.delete();
SQLiteDatabase.query();
d、关闭资源:(可选操作,每次获取数据库的时候数据库底层会自动关流,建议手动关闭)
SQLiteDatabase.close();
Cursor.close();

    1. MySql:

①MySql概述:

结构化查询语言,Structured Query Language的缩写

②JDBC简介:

a、JDBC:java数据库连接,Java DataBase Connectivity的缩写
b、开发人员安装了不同的数据库服务器(如MySQL和Oracle),则需要安装不同的数据库驱动,才能在java应用程序中连接该数据库并对该数据库的数据进行操作,而这样对开发人员来说是很麻烦的,于是乎SUN就提供了一套操作数据库的规范,该规范就是JDBC,不同数据库厂商实现了该规范(驱动),开发人员只要按照该规范开发就行了
c、JDBC规范的类在JDK中的

③JDBC编程步骤:

a、注册驱动:
方式一:DriverManager.registDriver(new com.mysql.jdbc.Driver())
注意该Driver所在的包是com.mysql.jdbc.,而不是java.sql.包中
该种方式不建议使用,原因如下:
****严重依赖具体的数据库驱动程序,DriverManager是java.sql.*包中的
如果改用Orcal数据库,则得改程序
****会导致数据库的驱动程序注册2次,DriverManager在类一加载的时候
就注册了一次,后面再new com.mysql.jdbc.Driver()又注册一次
(查看源代码)
方式二:Class.forName("com.mysql.jdbc.Driver");开发用此方式,次方式避免了a中方式一出现的问题
b、建立与数据库的链接:java.sql.Connection,所有的与数据库的交互都必须在链接的基础上进行操作
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day12","root", "xiaruri");
注:url的固定格式写法要记住:"jdbc:mysql://localhost:3306/day12"
jdbc:代表协议 mysql:代表子协议 localhost:3306:代表主机和端口 day12:代表数据库
root:代表MySQL服务器用户名 xiaruri:用户名密码
实际开发中需把传进去的三个字符串抽取出来,写成配置文件,通过读取配置文件形式将读取到的传进去,这样避免换数据库时改程序,只需改配置文件即可
c、获取代表SQL语句对象Statement stmt = conn.createStatement();
d、执行SQL语句 String sql = "select id,name,password,email,birthday from users";
e、如果有结果集,会被封装成一个ResultSet对象ResultSet rs = stmt.executeQuery(sql);
f、遍历结果集
while(rs.next()){
//rs.getObject(1):结果中每条记录的列索引从1开始。开发JDBC框架时使用
System.out.println(rs.getObject("id")+"\t"+rs.getObject("name")+"\t"+
rs.getObject("password")+"\t"+rs.getObject("email")+
"\t"+rs.getObject("birthday"));
}
h、关闭使用的资源
rs.close();
stmt.close();
conn.close();

④开源的数据源框架:

a、可直接访问硬件
b、DBCP
DBCP是Apache软件基金组织下的开源连接池实现,使用DBCP数据源应用程序应在系统中增加如下
两个jar文件:
Commons-dbcp.jar:连接池的实现
Commons-pool.jar:连接池实现的依赖库
常用O-R Mapping映射工具
Hibernate CMP JPA(Java Persistent API)
Ibatis(后来改名为MyBatis)
Commons DbUtils(只是对JDBC简单封装)
Spring JDBC Template
DbUtils简介:QueryRunner
MyBatis简介:MyBatis的前身就是iBatis。她是一个数据持久层框架
MyBatis支持普通SQL查询、存储过程和高级映射的优秀持久层框架
消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索,MyBatis使用简单的XML或注解用于配置和原始映射 , 将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
c、C3P0

    1. SharedPreferences:

SharedPreferences对象就相当于一个可持久化的Map集合
通过put方法存储持久化数据,需要commit才有效
通过get获取持久化数据

(7)系统MediaPlayer的生命周期、图像、音频和视频多媒体开发技术

①MediaPlayer:最终播放音频、视频文件的都是通过MeidaPlayer播放

注:音频、视频解码器是C代码写的,所以MediaPlayer内部是通过JNI调用系统的C解码代码

a、MediaPlayer的生命周期的几种状态:

idle:当一个MediaPlayer对象被刚刚new出来或是调用了reset()方法后到达idle状态
initialized:初始化完成状态。执行setDataSource()方法后到达initialized状态
prepared:准备完成状态。执行同步准备prepare()或者异步准备prepareAsync()方法后到达prepared状态
注意prepare()是阻塞式方法,所以播放网络视频开发中都用prepareAsync()方法。prepareAsync()有回调函数
started:开始播放状态。执行start()或者seekTo()方法后到达started状态
paused:暂停播放状态。执行pause()方法后到达paused状态
stopped:停止播放状态。执行stop()方法后到达stopped状态
playbackComp:播放完成状态。
end:调用了release()方法后到达end状态
error:播放控制操作可能会失败,如不支持的音频/视频格式,缺少隔行扫描的音频/视频,分辨率太高,流超时等原因,一旦发生错误,MediaPlayer对象会进入到Error状态
MediaPlayer的两种创建方式:
****MediaPlayer mp = new MediaPlayer();//此种方法创建必须调用prepare()或者prepareAsync()才能start()
****MediaPlayer.create(Context context,int resId); //此种方法系统内部已经执行prepare()了,故可直接start()

b、MediaPlayer的监听事件

setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 网络流媒体播放结束监听器
setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 网络流媒体的缓冲监听器
setOnErrorListener(MediaPlayer.OnErrorListener listener) 错误信息监听器
setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener) 视频尺寸监听 器
setScreenOnWhilePlaying(boolean screenOn) 设置是否使用SurfaceHolder显示监听器

c、MediaPlayer的作用

****MediaPlayer通常和Service结合播放音频文件
****MediaPlayer通常和SurfaceView结合播放视频文件
播放应用的资源文件
播放应用的原始资源文件
播放外部存储器上的资源文件
播放网络资源文件

d、MediaPlayer的缺点

资源占用量较高,延迟时间较长,不支持多个音频同时播放

e、使用SoundPool播放音效

SoundPool使用音效池的概念来管理多个短促的音效。SoundPool主要用于播放密集、短促的音效。
SoundPool与MediaPlayer相比的优势是在于CPU资源占用量低和反应延迟下,另外SoundPool还支持自行设置声音的品质、音量、播放比率等参数

f、使用VideoView和MediaController播放视频

VideoView的概述:
VideoView的作用是显示和播放视频
VideoView封装了MediaPlayer,同时继承了SurfaceView
VideoView可以播放网络音频、视频文件,通常不支持rmvb格式的视频
使用VideoView播放视频的步骤:
创建VideoView组件
调用VideoView的setVideoPath(String path)或者setVideoURI(Uri uri)加载指定视频
调用VideoView的start()、stop()、pause()方法控制视频的播放

g、使用MediaPlayer和SurfaceView播放视频

②MediaRecorder:

手机一般都提供了麦克风硬件,而Android系统就可以利用该硬件来录制音频或者视频

③多媒体常识:

a、什么是多媒体

多媒体是计算机和视频技术的结合,实际上它是两个媒体;声音和图像,或者用现在的术语:音响和电视

b、常用的视频格式

Android系统默认:mp4、3gp
常用格式:ts、3gpp、3g2、3gpp2、avi、mkv、flv、divx、f4v、rm、rmvb、rv、wmv、asf、mov、mpg、v8、ram、mpeg、swf、m2v、asx、ra、ram、ndivx、xvid等

c、常用音频格式:

Android系统:mp3、ogg;
常用格式:wma、mid、m4a、xmf、aac、mpa、midi、ar等

d、常用图片格式:PNG、GIF、BMP、jpg
e、android的多媒体应用:

视频播放器
音频播放器
相机
图片浏览器
视频通话
MediaScanner:开机或者SDcard插入时到系统库中扫描图片、音频和视频多媒体文件

f、MediaPlayer如何封装软解码:

在MediaPlayer类里面有一个静态代码块,该静态代码块完成调用用C语言编写的解码代码。

g、国内各个视频网站采用的解码框架:

优酷、搜狐、奇艺、pps、暴风影音土豆、56网都是用的ffmpeg
pptv已经使用p2p技术
点对点技术(peer-to-peer, 简称P2P)又称对等互联网络技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较少的几台服务器上。P2P网络通常用于通过Ad Hoc连接来连接节点。这类网络可以用于多种用途,各种档案分享软件已经得到了广泛的使用。P2P技术也被使用在类似VoIP等实时媒体业务的数据通信中。

h、当播放过程出错处理机制:

提示用户播放错误
重新播放

使用第三方播放器

④能实现万能播放的框架:

概述:虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但系统支持的格式、性能等各方面都十分有限 , 所以我们可以利用开源项目VLC、ffmpeg或者Vitamio来打造属于自己的Android万能播放器。

a、VLC框架:

VLC是一个开源项目,基于ffmpeg框架的自定义播放器。其中LibVLC是VLC的核心部分,就相当于MediaPlayer类
VLC一个最主要的部分,它可以播放各种类型的媒体文件和流媒体文件,并且可以创造媒体流并保存成各种格式的媒体文件
VLC是一种跨平台的媒体播放器和流媒体服务器,最初为videolan的客户端,它是一种非常简便的多媒体播放器,
它可以用来播放各种各样的音视频的格式文件(MPEG-1、MPEG-2、MPEG- 4、DivX、WMV、mp3、OGG、Vorbis、AC3、AAC等等)流媒体协议
最具特色的功能是可以边下载边观看Divx媒体文件,并可以播放不完全的AVI文件。并且支持界面的更改。
缺点:有C/C++代码,还有Java代码,代码太庞大

b、ffmpeg框架:

优点:轻量级框架,易于维护
FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案
FFMPEG几乎为你把所有的繁重工作都做了,比如解码、编码、复用和解复用。
这使得多媒体应用程序变得容易编写。它是一个简单的,用C编写的,快速的并且能够解码
几乎所有你能用到的格式,当然也包括编码多种格式。
FFmpeg支持MPEG、DivX、MPEG4、AC3、DV、FLV等40多种编码,支持AVI、MPEG、OGG、Matroska、ASF等90多种解码
FFmpeg主目录下主要有libavcodec、libavformat和libavutil等子目录。其中libavcodec用于存放各个encode/decode模块
libavformat用于存放muxer/demuxer模块,libavutil用于存放内存操作等辅助性模块

c、vitamio框架:

vitamio也是基于ffmpeg开源框架
VPlayer是vitamio的一个产品,vitamio和VPlayer是同一个团队开发的,VPlayer能播放的vitamio也能播放
vitamio的成功案例:
国内:VPlayer、熊猫影音、321影音等
国外:Tvltaliane、Dizi TV等
vitamio支持的网络协议:m3u8 , MMS , RTSP (RTP, SDP) , HTTP流式传输(progressive streaming) , HTTP Live Streaming (M3U8), Android 2.1+
vitamio的组成:vitamio.jar , ARMv-7-NEON.apk
四个解码器:ARMv-7-NEON.apk , VFP.apk , ARMv6.apk , ARMv5.apk
注:vitamio根据手机CPU型号安装对应的解码器,只安装一个解码器。
vitamio不是万能的,因为手机上的Android系统都被手机厂商改过,所以vitamio不支持所有的手机,但是支持大部分的手机。
解码:
硬解码:用系统接口实现的播放器。
软解码:不用系统接口实现的播放器。
注:系统播放器是硬解码。硬解码视频质量比软解码质量好,系统播放器的播放质量肯定比第三方播放器的播放质量好。

d、流媒体:

VLS:是一种流服务器,专门用来解决流的各种问题,它也具有一些VLC的特征。videolan作为服务器可以输出http,rtp,rtsp的流。
流媒体概述:
所谓流媒体是指采用流式传输的方式在Internet播放的媒体格式。
流媒体又叫流式媒体,它是指商家用一个视频传送服务器把节目当成数据包发出,传送到网络上。
用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显示出来。
流媒体以流的方式在网络中传输音频、视频和多媒体文件的形式。
流媒体文件格式是支持采用流式传输及播放的媒体格式。
流式传输方式是将视频和音频等多媒体文件经过特殊的压缩方式分成一个个压缩包,
由服务器向用户计算机连续、实时传送。在采用流式传输方式的系统中,用户不必像非流式播放那样等到整个文件 , 全部下载完毕后才能看到当中的内容,而是只需要经过几秒钟或几十秒的启动延时即可在用户计算机上利用 , 相应的播放器对压缩的视频或音频等流式媒体文件进行播放,剩余的部分将继续进行下载,直至播放完毕。

⑤如何实现视频的高质量播放:

高清、加载快、拖动快、没有广告

(8)JavaScript、AJAX技术,通过JQuery完成应用与服务器的异步交互和数据局部刷新
    1. JavaScript

①Aptana:

a、概述:

Aptana是一个非常强大的、开源的、专注于JavaScript的Ajax开发IDE(Integrated Drive Electronics的缩写,即电子集成驱动器)

b、Aptana功能:JavaScript、HTML、CSS语言的代码提示功能

OutLiner视图
代码语法错误提示
调试JavaScript
支持流行的AJAX框架的代码提示功能

②JavaScript知识:

a、浏览器对象Window:

组成:
document:文档对象
links:链接对象数组
forms:表单对象数组
images:图片对象数组
frame:框架对象
location:位置对象
history:历史对象

③DOM:Document Object Mode:文档对象模型

④Node:节点的CRUD

    1. Ajax:
(1)什么是AJAX?

Asynchronous JavaScript And XML的缩写。
允许浏览器与服务器通信而无须刷新当前页面的技术叫做AJAX技术。

(2)浏览器与服务器交互的两种方式

①普通B/S模式(同步):

提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事

②AJAX技术(异步):异步: 请求通过事件触发->服务器处理(这时浏览器仍然可以作其他事情)->处理完毕

(3)同步和异步的概念:

同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式

(4)AJAX技术的应用:

Google地图、几乎所有的网站现在都采用AJAX这种不用刷新的技术。

(5)不用刷新的技术:

①Flash
②Java Applet
③框架
④隐藏的iframe
⑤XMLHttpRequest
该对象是对JavaScript的一个扩展,可使网页与服务器进行通信。是创 建Ajax应用的最佳选择。实际上通常把Ajax当成XMLHttpRequest对象的代名词

(6)AJAX技术的原理:

①Ajax的核心是JavaScript对象XmlHttpRequest。

该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。
简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。

②AJAX采用异步交互过程。AJAX在用户与服务器之间引入一个中间媒介,从而消除了网络交互过程中的处理—等待—处理—等待缺点。

(7)AJAX包含的技术:

AJAX并不是一项新的技术,它是多种技术的结合,它包括Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest。

(8)AJAX技术的缺陷:

①依赖浏览器的支持,目前IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持AJAX
②对流媒体的支持没有FLASH、Java Applet好。
③手机、PAD还不能很好的支持AJAX
④AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的,这容易让用户搞不清楚现在页面上的数据是旧的还是更新过的

    1. JQuery:

①JQuery产生的原因:

为了简化JavaScript的开发, 一些JavsScript库诞生了。
当前流行的 JavaScript 库有: jQuery, MooTools, Prototype, Dojo, YUI

②JQuery是什么?

a、jQuery是继prototype之后又一个优秀的Javascript框架。其宗旨是——WRITE LESS,DO MORE,写更少的代码,做更多的事情。
b、它是轻量级的js库(压缩后只有21k),这是其它的js库所不及的,它兼容CSS3,还兼容各种浏览器(IE 6.0+,FF 1.5+,Safari 2.0+,Opera 9.0+)
c、jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互
d、jQuery能够使用户的html页保持代码和html内容分离,也就是说,不用再在html里面插入一堆js来调用命令了,只需定义id即可

③什么是JQuery对象?

jQuery 对象就是通过jQuery包装DOM对象后产生的对象
虽然jQuery对象是包装DOM对象后产生的,但是jQuery无法使用DOM对象的任何方法,同理DOM对象也不能使用jQuery里的方法.乱使用会报错

(9)AsyncTask和AsyncQueryHandler框架
    1. AsyncTask:

①AsyncTask概述:

AsyncTask是Android 1.5提供的一个轻量级的异步任务工具,是一个封装好的后台任务类。

②AsyncTask使用原则:

a、AsyncTask实例必须在主界面线程中创建
b、execute方法必须在主界面线程中执行
c、不要手动的调用onPreExecute、doInBackground、onPostExecute和onProgressUpdate方法
d、多次调用将会出现异常

③AsyncTask和Handler的异同点:

a、相同点:AsyncTask和Handler都能通过主线程和子线程之间的通信更新主界面
b、不同点:Handler比较麻烦,而AsyncTask使任务更加方便,而且AsyncTask过程可控。
对于多个后台任务时,使用Handler代码结构清晰简单;而使用多个AsyncTask时容易发生异常

    1. AsyncQueryHandler:

①AsyncQueryHandler概述:

a、AsyncQueryHandler继承于Handler

②AsyncQueryHandler的作用:

对ContentProvider提供的数据进行增删改查。

③AsyncQueryHandler的工作机制:

注:AsyncQueryHandler内部需要Handler、Looper、Message、HandlerThread、WorkerHandler和WorkerArgs配合使用完成异步任务

a、创建AsyncQueryHandler对象时,会调用系统的AsyncQueryHandler构造方法,在AsyncQueryHandler构造方法里,系统会进行如下操作:创建并开启一个HandlerThread、同时初始化Looper对象和Handler对象
b、当调用AsyncQueryHandler的startQuery、startInsert、startUpdate或者startDelete方法时

就会执行相应的增删改查方法,在AsyncQueryHandler的增删改查方法里面先通过Handler对象初始化Message对象,然后再初始化一个WorkerArgs对象,将任务参数信息封装到WorkerArgs对象中,最后再通过Handler对象的sengMessage方法将异步任务的消息发送出去

c、WorkerHandler收到消息后调用其handleMessage方法,在该方法里对异步任务的操作类型进行判断,然后执行与之对应的处理
d、最后回调指定的异步任务执行完成的回调方法,该回调方法系统是空实现,需要用户自己根据自己的业务去重写

④AsyncQueryHandler的使用注意事项:

大数据时会出现ANR异常,故需要优化。

(10)aidl开发:
    1. 什么是aidl?aidl就是Android接口定义语言,即Android Interface Definition Language的缩写,是Google提供的一个规范。
    1. aidl技术的作用:
      (可以先阐述服务的两种开启方式再开始回答这个问题)
      当服务调用者和服务不在同一个应用,此时服务调用者想通过远程绑定服务调用服务里面的方法就必须得通过aidl技术。
    1. 使用aidl技术的步骤:

①在服务中定义好方法

分析:我们不能去new一个服务,也就不能拿到一个服务对象的引用,拿不到服务对象的引用,也就不能通过服务对象的引用来调用服务中的方法 , 那么我们通过什么方式才能调用服务的方法呢?我们可以通过一个中间人来实现调用服务里面的方法,这个中间人就是接口。
而通过aidl技术可将服务应用中的接口和调用者应用中的接口变成同一个接口 , 就好比我们要请李宇春唱歌就得通过她的经纪人

②定义一个接口,并在接口中声明方法

③通过绑定服务的方法开启的服务会调用服务的onBind方法,而执行onBind方法会返回一个IBinder接口对象,而Binder是IBinder接口的实现类,故我们可以自定义一个内部类MyBinder继承Binder同时实现步骤②中定义好的接口,实现接口未实现的方法。
此时MyBinder就相当于一个中间人,通过调用这个中间人的方法我们就可以间接的调用服务中的方法

④进入服务的应用的本地目录,将服务中的接口文件后缀名改为aidl,同时将接口中的权限修饰符去掉(此时会在英语的gen目录生成相对应的.java文件);
进入调用服务的应用的本地目录,将接口文件的后缀名改为aidl,同时将接口中的权限修饰符去掉(此时会在英语的gen目录生成相对应的.java文件);
这样就保证两个应用中相同包相同声明的接口是同一个接口,进而可以通过该中间人接口远程调用服务里面的方法。

⑤将服务中自定义的内部类MyBinder改为继承Stub;
将远程绑定服务调用服务方法的代码中ServiceConnection类的onServiceConnected方法返回的IBinder接口,通过Stub.asInterface(IBinder)方法强转成我们自定义的中间人接口(只有强转为和服务中自定义的接口类型才能调用服务中的方法)

(11)WebService调用技术:

①WebService调用技术的作用:调用网上提供的服务

②如何使用WebService:

a、登陆http://www.webxml.com.cn网站,确定我们要访问的WebService服务,查看其网上提供的使用API获取访问其WebService服务所需发送XML文件和接收的XML文件,了解使用说明
b、向网上服务端发送指定服务所需要的指定格式的XML文件
c、解析网上服务端返回的XML文件
WebService是发布在网络上的API,可以通过发送XML调用,WebService返回结果也是XML数据
WebService没有语言限制,只要可以发送XML数据和接收XML数据即

(12)常用设计模式和算法:
  • (1) 常用设计模式:

注:什么叫设计模式?解决某类问题行之有效的方法,是一种思想,是规律的总结

    1. 单例设计模式:
      ①概念:保证一个类在内存中只有唯一一个对象。
      ②实现单例设计模式的步骤:
      a、将构造函数私有化。构造函数私有化可避免其他程序创建该类对象
      b、在本类中创建一个私有的该类对象
      c、对外提供一个公共访问方式,为了方便其他程序访问到该类对象
      ③单例设计模式的两种方式:
a、饿汉式:类一加载就创建对象
class Student{
private Student(){}
private static final Student s = new Student();
public static Student getInstance(){
    return s;
 }
}
b、饱汉式:使用时才创建该对象
class Student{
private Student(){}
private static final Student s = null;
public static Student getInstance(){
    if(s==null) {
        //线程1就进来了,线程2就进来了。
        s = new Student();
    }
    return s;
  }
}
c、饿汉式和饱汉式的区别:

****饿汉式是类一加载进内存就创建好了对象;而懒汉式则是类加载进内存的时候,对象还没有存在,要使用该对象的时候再new出来
****懒汉式是延迟加载,如果多个线程同时操作懒汉式时就有可能出现线程安全问题
为解决懒汉式的线程安全问题,解决线程安全问题可以加同步来解决。
但是加了同步之后,每一次都要比较锁,效率就变慢了,可以通过双重判断来提高程序效率。
注:开发常用饿汉式,因为饿汉式简单安全。懒汉式多线程的时候容易发生问题

④单例设计模式的应用:

当需要保证某个类在内存中有且仅有一个实例对象时,就用单例设计模式。比如java的Runtime类、Class类都是采用的单例设计模式

    1. 工厂模式:
      ①作用和好处:作用:提供创建对象的接口
      好处:
      a、隐藏创建细节
      b、需要创建新对象时直接在配置文件修改就行,方便灵活

②工厂模式的分类:

a、简单工厂模式:不利于产生系列产品
b、工厂方法模式:多形性工厂
c、抽象工厂模式:又称为工具箱,产生产品族,但不利于产生新的产品

③工厂模式的应用:如XML文件的几种解析方法如DOM、SAX、PULL在创建解析器时都是用的工厂模式
④缺点:缺点是当产品修改时,工厂类也要做相应的修改。

    1. 模板模式:

①概念:

定义一个操作中算法的骨架,将一些步骤的执行交给子类去完成。
在定义功能时,功能的一部分是确定的,有一部分是不确定的,而且确定的部分在使用不确定的部分,可将不确定的部分暴露出去,由该类的子类去完成。

②模板设计模式的应用:

a、Servlet就是用的模板设计模式
b、如Android开发中的BaseActivity。几乎每个Activity都要执行findview、setview、监听事件和处理事件等操作。故我们可以将这些共同的操作抽取出来形成一个模板。
c、模板设计模式在一些开源框架中应用很多

    1. 代理模式:

①定义:为其他对象提供一种代理以控制对这个对象的访问
②代理模式的应用场景:

a、授权机制
b、不能直接访问对象,但又必须和这个对象进行交互

③代理模式如何用?

比如我要找李宇春唱歌,李宇春很忙,我只能找她经纪人,经纪人虽然不会唱歌,但是通过经纪人这个中间人可以调用李宇春唱歌。

    1. 策略模式:

①定义:

策略模式就是用来封装算法的。
策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

②概述:

策略模式把行为和环境分开。环境类负责维持和查询行为类,各种算法在具体的策略类中提供。
由于算法和环境独立开来,算法的增减,修改都不会影响到环境和客户端。

③策略模式的应用场景:

策略模式是用来封装算法的。
只要在不同时间应用不同的业务规则,就可以考虑用策略模式处理这种变化的可能性。

    1. 装饰模式:

①概念:

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。
动态给一个对象增加功能,这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。

    1. 适配器模式:

①概念:

将一个类的接口转换成客户希望的另外一个接口。适配器模式使原本由于接口不兼容而不能一起工作的那些类可以一起工作。

②应用场景:

两个类所做的事情相同或者相似,但是具有不同的接口时就可以考虑适配器模式。
-8) 观察者模式:

①概念:

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。
这个主题对象在状态发生变化时,会通知所有的观察者,使他们能够自己更新自己。
适配类可以根据参数返还一个合适的实例给客户端。

②概述:

所谓知己知彼百战不殆。

    1. 门面模式:

①概念:

外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类。

    1. 设计原则:

①单一职责原则:

a、概念:应该有且仅有一个原因引起类的变更 , 简称SRP,Single Responsibility Principle的缩写
b、单一职责的好处:
类的复杂性降低
代码可读性高
可维护性提高
变更引起的危险降低

②里氏替换原则:

a、概念:
所有引用基类的地方必须能透明的使用其子类的对象。
通俗的讲就是只要父类能出现的地方,我子类就可以出现,而且调用子类还不产生任何的错误或异常;
但是反过来就不行了,有子类出现的地方,父类未必就能适应。
b、里氏替换原则包含的意思:
子类必须完全的实现父类的方法
子类可以有自己的个性
覆盖或者实现父类的方法时输入参数可以被放大
覆盖或者实现父类的方法时输出结果可以被缩小

③依赖导致原则:

a、概念:
Dependence Inversion Principle
依赖倒置可以说是面向对象设计的标记,用哪种语言编写程序并不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程 , 即程序中所有的依赖关系都终止于抽象或者接口,那就是面向对象设计,反之就是过程化的设计了。

④接口隔离原则(Interface Segregation Principle):

a、概念:
第一种定义:客户端不应该依赖它不需用的接口
第二种定义:类间的依赖关系应该建立在最小的接口上 , 通俗的讲,就是接口尽量细化,同时接口中的方法尽量的少。
b、接口隔离包含的四层意思:
接口要尽量小
接口要高内聚:高内聚就是提高接口、类、模块的处理能力,减少对外的交互
定制服务
接口设计是有限度的
一个接口只服务于一个子模块或者业务逻辑

⑤迪米特法则(Low Of Demeter):

a、概念:\也叫最少知识原则 , 通俗的讲一个类对自己需要耦合或者调用的类应该知道的最少,你类内部是怎么复杂、怎么的纠缠不清都和我没关系,
那是你的类内部的事情,我就知道你提供的这么多public方法,我就调用这个
b、迪米特法则的四层意思:
只和朋友交流:
出现在成员变量、方法的输入输出参数中的类被称为成员朋友类
朋友间也是有距离的:迪米特法则就要求类"小气"一点,尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private,package-private、protected等访问权限
是自己的就是自己的:如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中
谨慎使用Serializable

⑥开闭原则(Open Close Principle):

a、概念:软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化
软件实体:项目或软件产品中按照一个的逻辑规则划分的模块
抽象接口或类
方法
b、为什么要用开闭原则:
开闭原则是最基础的原则
开闭原则非常重要:
开闭原则对测试的影响
开闭原则可以提高复用性
开闭原则可以提高可维护性
面向对象开发的要求
c、如何使用开闭原则:
抽象约束
参数控制模块行为
制定项目章程
封装变化

(13)html5和PhoneGAP框架:
(14)回调函数:

①回调函数的概念:

回调函数就是那些自己写的,但是不是自己来调用,而是在需要的时候给别人来调用的函数。比如消息回应函数。
即生成对象的时候,不调用对象的方法,而作为参数传递下去,在需要再调用。

(15)UML语言:

①UML作用:

消除了不同建模语言之间的差异
提供了一个客户、需求 分析、架构设计、软件实现和运维部署部门之间共同交流的语言
集成了优秀的开发实践成果和经验

②UML分类:

静态图:
类图(类之间的关系:依赖、泛化、实现和关联(关联又分为聚合和组合))
对象图
包图
行为图:
活动图
状态图
用例图:用例图(用例之间的关系:泛化、包含和扩展)
交互图:
顺序图
协作图
实现图:
组件图
部署图

③UML的建模工具:

Rose:
Visio:
Power Designer:

④OO设计原则:

开闭原则
里氏代换原则
依赖倒置原则
接口分离原则

(16)面向对象:
    1. 概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象强调具备功能的对象,
    1. 思想特点好处:

A:是符合人们思考习惯的一种思想;
B:将复杂的事情简单化了;
C:将程序员从执行者变成了指挥者;
注:比如我要达到某种结果我要是用某个功能,我就寻找能帮我达到该结果的功能的对象,如果该对象具备了该功能 , 那么我拿到该对象,也就可以使用该对象的功能。如我要洗衣服我就买洗衣机,至于怎么洗我不管。

    1. 特征:

封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象

    1. 面向对象设计的重要经验:谁拥有数据,谁就对外提供操作这些数据的方法。

如:
人在黑板上画圆:
画圆需要知道圆心的位置和圆的半径,而圆心的位置和圆的半径只有圆自己最清楚,所以画圆的方法是圆的方法。
列车司机紧急刹车:
刹车的方法是司机的还是车的呢?同样,具体刹车的动作、怎么刹车只有车是清楚的,人只是发个刹车的信号给车,所以刹车的方法是车的
面向对象的面试题:
两块石头磨成一把石刀,石刀可以将树看成木材,木材可以做出椅子:
石头磨成石刀是哪个对象的方法呢?如果是石头内部的方法的话,那么石头磨成石刀,石头自己都没了,所以石头磨成石刀不是石头内部的方法,故石头变成石刀应该是一个石头加工厂的方法,将石头磨成石刀。
石刀将树看成木材,所以石刀应该有一个将树看成木材的方法
木材可以做成椅子,所以应该有一个木材加工厂,该加工厂有一个接收木材然后加工成椅子的方法。
球从一根绳子的一端移动到另一端:球这个对象应该有移动到下一个点的方法 , 绳子这个对象应该有提供下个点是哪个点的方法,以通知小球移动的方向

(18)Android四大组件:
    1. Activity
    1. Service:

①服务的两种开启方式:

a、startService:
特点:服务一旦开启,就会在后台长期运行 , 服务的开启者跟服务没什么关系
b、bindService:

特点:调用者挂了,服务也跟着挂。即不求同日生但求同日死
注:通过bindService开启的服务,用完一定要先unbindService再destroy,否则会报异常。

    1. ContentProvider
    1. BroadcastReceiver
(19)代码优化:
    1. 代码优化原则:

①时间换时间:

如禁用电脑的一些开机启动项,通过减少这些没必要的启动项的时间从而节省开机时间
如网站界面上数据的分批获取,AJAX技术

②时间换空间:

如拷贝文件时new一个字节数组当缓冲器,即byte[] buffer = new byte[1024]。
为什么只new一个1024个字节的数组呢,new一个更大的字节数组不是一下就把文件拷贝完了么?这么做就是为了牺牲时间节省有限的内存空间

③空间换时间:

如用Windows系统自带的搜索文件的功能搜索文件时会很慢,但是我们牺牲电脑硬盘空间安装一个everything软件来搜索文件就特别快

④控件换空间:如虚拟内存

(20)手机定位、地图:
    1. Android手机定位的三种方式:

①基站定位:

根据手机基带和附近的基站,通过手机信号的强弱来定位手机。
但是这种定位方式的精确度跟手机离基站的远近以及手机附近基站的密集程度有关系。
精度为20米-2000米不等。

②wifi定位(也叫网络定位):

当手机连接网络的时候,会动态获取一个ip地址,运营商会让ip跟实际位置有一个一一对应关系,所以通过ip地址也可以定位手机。
比如Google公司的谷歌纵横。
因为手机获取到的ip都是运营商根据手机所处位置动态分配的ip,所以这种方式进行手机定位的精确度比较差,精确度为200米+

③GPS定位:

手机都会自带一个比较便宜的非专业的A-GPS模块,通过免费的光波的方式和卫星进行通信。
因为是通过光波的方式,所以就要求头顶必须空旷。
像汽车上比较专业的GPS设备,会进行信号一些放大和增益,进行手机定位也就比较不受限制和精确。
精确度跟GPS模块的精度有关,通常为2米-10米。

    1. Google Map:

①获取Google Map API的Key:

为了在应用程序中调用Google Map,必须先获取Google Map API的Key。

②安装Google Map API插件:

Android SDK默认并不支持Google Map,为了得到支持Google Map的SDK,必须为Android SDK增加相应的插件:AVD。

③创建支持Google Map API的虚拟设备:

为Android SDK安装Google Map API插件后,还需要创建一个支持Google Map API的虚拟设备。

④Google Map API:

a、MapView:为了在Android平台上调用Google Map服务,Google Map提供了一个MapView,这个MapView的用法就像普通的ImageView一样,直接在界面布局文件中定义它,然后在程序中控制该组件即可。
b、MapController:通过MapView.getController()可获取MapController对象 , MapController可对MapView进行控制,比如控制地图定位到指定位置或者地图放大、缩小等
c、Overlay:通过MapView.getOverlay()可获取Overlay对象 , Overlay是附加在Google Map上的附加图片,应用可以控制向Google Map上添加任意多个Overlay
d、GeoPoint:GeoPoint类表示Google Map上的指定点 , GeoPoint就是对经度和纬度的封装

⑤使用Google Map API定位的步骤:

a、获取MapView对应的MapController对象
b、根据经度、纬度值创建GeoPoint对象
c、调用MapView控件所关联的MapController对象的animateTo(GeoPoint point)方法定位到指定位置
注意:
在布局文件中引入MapView要通过包名.类名的方式
在布局文件中定义MapView必须要设置android:apiKey,其值为①中申请到的Key

⑥GPS导航:

把GPS导航和Google Map结合起来使用,可以非常方便的开发出GPS导航应用
a、通过Context.getSystemService(Context.LOCATION_SERVICE)方法获取LocationManager对象
b、通过LocationManager对象每隔一段时间获取GPS定位信息
c、根据LocationManager对象每隔一段时间获取的GPS定位信息,通过MapView将地图定位到指定位置

⑦根据地址定位:

Google Map必须通过经度和纬度来进行定位,而普通用户不可能记住某个位置的经度和纬度,所以对普通用户来说根据地址定位才是有价值的地图应用
为此,需要进行如下两个操作:
a、地址解析:把字符串地址转换为经、纬度
b、反向地址解析:把经、纬度转换为字符串地址
Android为地址解析提供了Geocoder工具类,该工具类提供如下两个方法进行地址解析和反向地址解析
a、List<Address> getFromLocation(double latitude, double longtitude, int maxResults)
执行地址解析,把经、纬度值转换为字符串地址
b、List<Address> getFromLocationName(String locationName, int maxResults)
执行反向地址解析,将字符串地址转换为经、纬度值

    1. 火星坐标系统:

①现在绝大多数的GPS获取到的经度和纬度都是美国的卫星,我们国内也有北斗卫星,但是至今没给民用。

通过美国卫星获取到的经、纬度是国际标准的经、纬度;
而国际标准的经纬度在中国地图上显示的位置是不准确的;
为了拿国际标准的经纬度在中国地图上获取到准确的位置,需要把国际标准的经纬度转换成中国的火星坐标才能获取到准确的位置

(21)JDK1.5新特性:
(22)联网机制:
    1. 手机端的通信渠道:

①WLAN(wi-fi):无线局域网

Wi-fi是无线局域网最常用的一种无线技术,wi-fi向局域网内所有ip发送一个数据包(UDP)
覆盖范围:100米以内

②手机APN(Access Point Name):接入点

a、基站覆盖范围:1-1.5公里
b、Wap方式:网关 国外是没有的,这种方式是中国特有的,具有地域性。
Wap的ip和端口:ip:10.0.0.172 端口:80
Wap通信机制:手机端的请求网络资源,先经过Wap,Wap再将请求转到网络资源
Wap作用:在中间端提供增值业务
c、Net方式:
Net通信机制:手机端请求网络资源直接连接到网路资源路径,不需要通过任何中间接口

    1. 手机端和服务器通信的方式:

①Socket:

比如:豌豆荚(USB、WIFI)、聊天工具等
USB连接:当手机通过USB连接PC端时,读取连接手机的设备PID和VID等信息,然后找手机驱动,如果发现驱动没安装过就自动帮你安装,如果驱动已安装则不再安装,安装完手机驱动后就通过Socket指定一个端口读取手机信息
wi-fi连接:PC端应用会向局域网内所有的ip通过UDP发送一个数据包 , 数据实时交互较高时也会用到Socket通信:通过Socket写一个长连接,每隔一段时间给服务器发送数据包。这个数据包称为心跳,间隔时间通常为30秒比如股票交易、贵金属的交易应用等都会实时跟服务器交互数据

②HttpUrlConnectioon:

可以理解为一个工具类

③HttpClient:

HttpClient是一个开源框架
作用:解决和服务器进行交互有网关(Wap)存在时的地域局限性
比如北京和上海的网关(Wap)是有差异的,如果通过Wap渠道通信,在北京开发的应用,拿到上海去用会出现问题 , 连接10次网络,可能才成功3、4次。

    1. 在写手机端连接工具之前的准备工作:

①判断手机当前的网络类型:

判断是WiFi接入还是APN接入 , 如果是APN接入则需要进行特别处理,即需要设置APN的信息(获取手机当前处于活动状态的APN的ip和端口)

(23)软件测试:

①monkey测试:Android自带的测试工具

②testing:提供很多测试工具

③百度测试中心:

(24)软件在不同屏幕的手机上的适配;
    1. 屏幕适配原则:

①开发时单位尽量采用dip或者dp单位
②定义布局时尽量采用相对布局或者线性布局或者帧布局
③当屏幕过小或者内容过多时采用ScrollView控件将整个布局文件进行包裹
④点9图片
⑤在AndroidManifest.xml文件的<manifest>元素如下添加子元素

<supports-screens 
    android:largeScreens="true"
    android:normalScreens="true" 
    android:anyDensity="true"
    android:smallScreens="true">
</supports-screens>         
(25)MVC开发模式:
(26)垃圾短信过滤

A.定义类继承BroadcastReceiver
B.在清单中配置<receiver><action>的name值为:android.provider.Telephony.SMS_RECEIVED
权限permission-->android.permission.RECEIVE_SMS

C.在onReceive(context,intent)中获取数据

        Bundle bundle = intent.getExtras();
        /*
         * Set<String> set = bundle.keySet(); for(String str : set)
         * System.out.println(str); 得到bundle中的字段--->pdus
         */
        Object[] objs = (Object[]) bundle.get("pdus");//返回一个Object[]数组
        for (Object obj : objs) {
            //每个一个obj对象又是一个byte[]数组
             SmsMessage sms = SmsMessage.createFromPdu((byte[]) obj);
            "主体内容:"+sms.getMessageBody()
            "发信人:"+sms.getOriginatingAddress()
            "服务中心号码:"+sms.getServiceCenterAddress()
                Date date = new Date(sms.getTimestampMillis());
            "时间:"+new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(date)
        }

D.根据不同需求,短信进行过滤,还未能更改,更改信息封装数据很麻烦,只能abortBroadcast();

1、自定义控件项目

(1)SplashActivity:
1)Splash的作用:

①实际开发中Splash的作用一是展现产品的logo,提升产品的知名度
②Splash的第二个作用是可以根据不同的日期和时间,展现不同的界面,比如情人节版、新年版等,提升用户体验(可顺便提一下用户体验是现在炒得比较火的一个概念,任何一个网站任何一个软件都在说要提高用户体验,所以现在小的公司都有UI工程师,大的公司都有UE工程师)
③Splash的第三个作用是可以用来完成程序的初始化。比如数据库的初始化、文件配置的拷贝和读取等操作
④Splash还可以进行检查网络、检查升级、创建程序缓存路径、检查SDCard是否存在以及日志等操作。

2)动画:

刚刚Splash界面的火柴人动画和倒计时的动画都是帧动画。
在界面一加载的时候就启动该动画,要注意此处动画的启动不能通过控件.startAnimation的方式启动,因为此时帧动画所需的图片资源还没加载完成,得通过控件.post的方式,开启一个子线程,在子线程中通过动画.start的方法启动动画。

(2)HomeActivity:
1)概述:

①走马灯文字(android:ellipsize="marquee"):
a、文字走马灯效果的应用场景:在空间比较有限而需要展示的文字信息比较多时,就可以考虑采用走马灯效果来展示
b、文字走马灯效果的实现:通过自定义控件继承TextView来实现文字的走马灯效果。
实现文字走马灯效果的前提是该控件必须获取焦点,而默认情况下所有的TextView是获取不到焦点的 , 所以我们要在继承TextView的自定义控件复写isFocused方法,并且返回true,这样改空间就可以获取焦点,也就可以在界面一加载的时候实现走马灯效果
②界面布局:Home主界面控件的展示通过GridView来实现。我们开发中显示数据最常用的一个控件就是ListView,其实GridView和ListView都是继承自同一个父类AbsListView,所以他们的用法差不多,都是通过给该控件设置适配器来实现数据的显示
③底部菜单栏:这个底部菜单栏我是扒的早期的优酷手机端的实现效果。我觉得这种菜单比较炫,所以就自己实现着玩 , 实现起来也比较简单,布局通过相对布局的方式来实现,主要是动画的实现和点击事件的处理。
动画是一个旋转动画,点击事件就是一些简单的逻辑判断和空间的显示和隐藏控制
④点击GridView选项的动画处理:通过overridePendingTransition来实现界面切换时的动画效果 , 我这里的动画是缩放动画(Scale),点击某个选项时,旧的界面缩小到该选项的位置,新的界面再从该选项的位置放大到屏幕大小

(3)ImageView:
1)项目中知识点概述:这个ImageView模块主要是用来展示图片的一些控件。

①ViewPager:
a、ViewPager概述:顶部导航部分是通过ViewPager实现的。
ViewPager是一个第三方标签,在android_support-v4.jar包中,使用的时候需要通过包名.类名的方式导入。
通过给ViewPager设置PagerAdapter,复写PagerAdapter的instantiateItem方法来实例化要现实的图片和destroyItem方法去除图片。
ViewPager控件不能像Gallery一样一次滑动多张图片,ViewPager一次只能滑动一张图片。为什么ViewPager只能滑动一张图片呢?
因为ViewPager显示的时候只加载三张图片,即当前显示的图片、当前显示图片的前一张图片和后一张图片。
b、如何实现ViewPager中图片自动滑动:每隔2秒钟,ViewPager控件里面的图片会自定切换到下一张图片,当切换到最后一张图片时再切换回第一张图片。
这可以通过计时器Timer或者线程池执行者ScheduledExecutorService来实现ViewPger控件图片的自动切换。
但是,Timer存在一些bug,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;
而ScheduledThreadExecutor只支持相对时间。比如你用Timer定时器每隔五分钟执行一个任务,任务跑起来后,你去修改当前系统的时钟,此时就会对当前正在执行的任务造成影响。而用ScheduledExecutorService的的话,任务跑起来后,你修改系统时间对任务是没有影响的。
所以在JDK1.5以后就逐渐不用Timer了,开发中都用ScheduledExecutorService。
c、如何实现ViewPager中文字和点随着图片的滑动变化:当ViePager控件的图片自动切换或者手动切换时,其中的文字信息和点状态会随之改变。
这是通过给ViewPager设置图片改变事件监听器来实现。
当OnPageChangeListener监听到ViewPager显示的图片改变时会调用其onPageSelected方法,我们可以在该方法里面实现。
此实现过程需要一个变量来记录上一次ViewPager显示的图片的位置position。
②ScrollView:
a、ScrollView的概述:顶部的单选框是用RadioGroup实现的。当界面加载的时候根据要显示的图片数动态的创建相对应数目的RadioButton。图片的显示时通过自定义控件继承ViewGroup来实现的。
通过复写ViewGroup的onLayout完成子view在ViewGroup中的布局显示。
onLayout方法实现ViewGroup中子View如何排列。当需要知道ViewGroup的子View如何排列时系统会自动调用此方法复写ViewGroup的onTouchEvent()方法,将触摸事件交给手势识别器GestureDetector处理,手势识别器可识别触摸的各种手势:点击、按下、长按、滚动、快速滑动等。通过复写GestureDetector的onScroll()方法实现缓慢滑动和复写onFling()方法实现快速滑动时切换图片缓慢滑动松开手指时先判断当前哪张图片滑过屏幕的中点,再通过View.scrollBy(dx, dy)或者Scroller.startScroll(startX, startY, dx, dy)方法将该图片移动到屏幕中显示,最后调用invalidate()方法更新界面快速滑动松开手指时会判断滑动的速度和加速度方向,再将当前显示的图片切换到下一张图片最后调用invalidate()方法更新界面 , 最后在继承ViewGroup的自定义控件中提供一个监听器,监听ViewGroup显示图片的改变。用来实现图片改变时,RadioGroup中相对应的RadioButton的状态变成选中。
③Gallery:
a、Gallery概述:图片的画廊+倒影效果实现起来就稍微复杂了,需要的API比较多,需要照相机Camera、旋转动画Transformation和矩阵Matrix来实现图片的变形显示,需要Bitmap、画布Canvas、画笔Paint等API来实现倒影图片的生成。另外需要处理的逻辑也稍微绕一点。
首先需要显示图片的画廊准备好:自定义控件继承Gallery,
在该继承Gallery的自定义控件中复写getChildStaticTransformation方法,该方法在Gallery中的图片显示状态发生改变时被调用,在该方法里我们可以根据图片显示的位置计算出该图片在Galery中显示的旋转位置;
同时该继承Gallery的自定义控件应该还有一个根据图片距离Gallery显示图片的中心的位置不同控制Gallery中
图片显示的大小、角度、亮度等信息的方法画廊准备好了,接下来就是准备画廊中要显示的图片:
自定义适配器继承BaseAdapter,该继承BaseAdapter的自定义控件提供一个生成倒影图片的方法。
在该生产倒影图片的方法中,处理源图片和倒影图片的间隔、遮罩效果、渐变效果、去除图片锯齿等操作
画廊和倒影图片都准备好后,接下来就给画廊设置自定义的适配器就OK了
④WaterFall:
a、图片瀑布流概述:图片瀑布流需要大量的图片资源,这也是我这个自定义控件二十几兆的原因之一。
这些图片资源因为比较大,所以存放在资产assets目录下的。为什么要存放在资产目录下而不是存放在res目录下呢?因为存放在res下的目录下的资源都会被自愿编译器编译,生成资源引用,当资源文件比较大时编译就比较麻烦,而放在assets目录下的资源会原封不动的拷贝到.apk文件中。
(3)Dialog:
1)Dialog概述:
Dialog也是一个应用非常广泛的控件,几乎所有的应用都用到这个控件。
在Android开发中,通知用户的方式有三种:一种是吐司通知,一种是状态栏通知,还有一种就是我们最常用的对话框通知。
而对话框通知又分为单选对话框、多选对话框、列表对话框、进度对话框等。
我这个三级地址联动是通过AlertDialog的内部类Builder来实现的,比较简单,只要是选择地址的一些逻辑处理和地址空间的显示隐藏。
用户登录界面是模仿的QQ登陆实现的。通过点击右边的下拉图标弹出内容为一个ListView的PopupWindow。
这里这个PopupWindow这么丑主要是因为它挂在Dialog下面的缘故,因为挂在Dialog下面,所以PopupWindow的高度就被限制了。
针对这种情况,把登陆界面弄成一个Activity就行了,我这里就是为了演示一下,实际开发中不会弄这么这么短这么丑的PopupWindow。
(4)ProgressBar:
1)ProgressBar概述:
①自定义水平进度条:
因为系统默认的进度条挺难看的,所以这里的进度条是自定义系统的水平进度条。
通过查看Android SDK资源目录res下的values文件夹中的styles.xml文件,该文件定义了Android系统所有的控件的预先样式。
在该文件里面找到关于水平进度条的样式的定义,接着查看系统progress_horizontal.xml文件,
直接拷贝progress_horizontal.xml,对其进行修改,就可以实现我们自定义的水平进度条的样式了。
②病毒文件扫描动画:
这个扫描动画是一个旋转动画。看这个动画不是匀速的,产生这个效果的原因主要是由动画的效果决定的,
因为动画本身默认的插入器就是先快后慢。
如果想去实现匀速的效果也比较容易,我们可以在水平进度条没扫描一个条目动画旋转二十度或者三十度来实现匀速的效果。
②病毒文件的扫描:
关于病毒软件的扫描,实现起来也比较简单。
杀毒软件的原理:
杀毒软件的原理就是比对文件的特征码。
所谓的杀毒软件其实就是一个文件清除器。为什么叫文件清除器呢?因为病毒就是一个应用程序,也就是一个文件。
那什么是病毒呢?那要看你怎么去定义了,所谓水能载舟亦能覆舟,一个道理。
如果一个软件,你用在好的方面,就是一个软件;如果你用在坏的方面,就是一个病毒。
所谓病毒扫描,就是根据文件的特征码去比对病毒数据库。
2)SeekBar概述:
这个显示和控制声音的控件是通过自定义控件继承View来实现的。也可以做成竖直的SeekBar来实现,竖直的SeekBar实现起来更简单。
该继承View的自定义控件通过复写View的onDraw方法将自己画出来,通过两种图片,一张表示声音的绿色条目和一张表示背景的灰色条目
onDraw方法根据当前音量分别将表示声音的绿色部分和不表示声音的灰色部分画出来
该继承View的自定义控件还提供一个调音接口和音量改变监听器,用来实现音量改变时改变控件的进度
(5)ListView:
1)ListView概述:
ListView的作用是显示数据。可以说我们开发中,应用的数据大部分都是通过ListView来显示,
像社交类应用好友的显示啊、新闻类应用新闻信息的显示啊、多媒体类应用多媒体文件的显示啊都是通过ListView来显示的
显示数据
ListView如何用?
首先要给ListView设置一个适配器Adapter,把要显示的数据交给适配器Adapter去处理,
另外ListView的getView方法每被调用一次显示一个条目,都伴随着一个旧的条目被移除,故为了优化ListView,
可以在getView()方法中重用旧条目convertView
还有ListView的getView方法中每执行一次findViewById方法时,都会加载相应布局的树状结构,再遍历该树状结构找到指定id,
当该布局的树状结构很复杂时,每次都查找id会比较麻烦,所以为了优化我们可以提供一个ViewHolder类,
用来记录布局中的所有控件,这样布局中的控件id只需查找一次,再用时,直接在ViewHolder类里面取
最后用ListView显示大数据时,还需要进行分批加载或分页显示处理
2)下拉刷新:
这个下拉刷新控件是通过自定义控件继承ListView实现的,通过ListView.addHeaderView方法将头部下拉刷新的组件添加到ListView中
创建布局文件的时候再通过包名.类名的方式引入自定义控件。
其中头部下拉刷新组件中下拉刷新箭头的指向和下拉刷新文字信息的更新通过监听触摸事件来实现,
当ListView显示的第一个条目的位置为0并且手指在屏幕Y轴方向上移动时,下拉刷新组件由下拉完成状态变成下拉刷新状态;
当手指继续在屏幕上移动且Y轴的位移大于下拉刷新组件的一半时,下拉刷新组件的状态由下拉刷新变为松开刷新状态
当松开手指时,下拉刷新组件的状态由松开刷新变成正在刷新
当正在刷新完成后,下拉刷新组件的状态就变成默认的下拉完成状态
3)分批分页处理:

2、智能短信分类管理器:
(1)项目概述:
智能短信分类管理器这个项目是联想和中国移动合作的项目,属于定制机,是一个系统级订制项目。
需要重新给系统打一个安装包,需要封装中国移动的一些信息,所以很多界面都需要重新做。
联想的手机系统不是Android的原生系统,是乐Phone2.5版本以后关于短信的一个应用。把短信系统重新进行了封装。
(2)五大功能模块:
1)会话列表,显示短信
使用Android自身提供的异步查询框架AsyncQueryHandler查询手机短信,查看系统短信源码TelephonyProvider
2)文件夹
对短信进行分类管理。分为收件箱、发件箱、已发送和草稿箱,并且对短信进行了日期分隔显示。
3)群组:
提供给用户根据短信自定义分组管理的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,796评论 25 707
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,969评论 3 119
  • 感恩 —— 爱人为了带我吃正宗的襄阳牛杂面,绕了好几圈,终于找到了,爱人先吃完,看着我吃的有点急,爱人说慢慢吃,不...
    慢慢花开阅读 151评论 0 0
  • 你听,长笛,是长笛之音在呼唤:我,来了!你,在哪儿? 长笛,低音婉转,曲调透明又悠扬,仿佛正在述说...
    段靖阅读 442评论 6 4
  • 写在前面:最近一直有一个疑惑,为什么我感觉区块链这个东西,已经黏上了我身体上的每一个触须,而身边竟还有人完全对此一...
    一夜读阅读 4,006评论 0 5