Android精典资料分析.docx
- 文档编号:17713880
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:48
- 大小:1.21MB
Android精典资料分析.docx
《Android精典资料分析.docx》由会员分享,可在线阅读,更多相关《Android精典资料分析.docx(48页珍藏版)》请在冰点文库上搜索。
Android精典资料分析
Java资料
TreeMap
TreeMap.headMap方法
TreeMap通过index取值的方法
TreeMap通过Key获取Index
Json
Java反射有参和无参
String
字符串分割
Stringnull值判断
List与数组互转
state与status区分
某年中2月有多少天
在Maven工程里运行Javamain方法
SOCKET
一、Socket通信简介
Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信。
两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。
而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。
那么,什么是socket?
Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。
通过建立socket连接,可为通信双方的数据传输传提供通道。
socket的主要特点有数据丢失率低,使用简单且易于移植。
1.1什么是SocketSocket
是一种抽象层,应用程序通过它来发送和接收数据,使用Socket可以将应用程序添加到网络中,与处于同一网络中的其他应用程序进行通信。
简单来说,Socket提供了程序内部与外界通信的端口并为通信双方的提供了数据传输通道。
1.2Socket的分类
根据不同的的底层协议,Socket的实现是多样化的。
本指南中只介绍TCP/IP协议族的内容,在这个协议族当中主要的Socket类型为流套接字(streamsocket)和数据报套接字(datagramsocket)。
流套接字将TCP作为其端对端协议,提供了一个可信赖的字节流服务。
数据报套接字使用UDP协议,提供数据打包发送服务。
下面,我们来认识一下这两种Socket
类型的基本实现模型。
1.3两种传输模式
1)、面向连接的传输:
基于TCP协议,可靠性高,但效率低;
2)、面向无连接的传输:
基于UDP协议,可靠性低,但效率高;
二、Socket基本通信模型
三、Socket基本实现原理
3.1基于TCP协议的Socket
服务器端首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept()方法接收客户端的数据。
accept()方法在没有数据进行接收的处于堵塞状态。
(Socketsocket=serversocket.accept()),一旦接收到数据,通过inputstream读取接收的数据。
客户端创建一个Socket对象,指定服务器端的ip地址和端口号(Socketsocket=newSocket("172.168.10.108",8080);),通过inputstream读取数据,获取服务器发出的数据(OutputStreamoutputstream=socket.getOutputStream()),最后将要发送的数据写入到outputstream即可进行TCP协议的socket数据传输。
3.2基于UDP协议的数据传输
服务器端首先创建一个DatagramSocket对象,并且指点监听的端口。
接下来创建一个空的DatagramSocket对象用于接收数据(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)),使用DatagramSocket的receive方法接收客户端发送的数据,receive()与serversocket的accepet()类似,在没有数据进行接收的处于堵塞状态。
客户端也创建个DatagramSocket对象,并且指点监听的端口。
接下来创建一个InetAddress对象,这个对象类似与一个网络的发送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定义要发送的一个字符串,创建一个DatagramPacket对象,并制定要讲这个数据报包发送到网络的那个地址以及端口号,最后使用DatagramSocket的对象的send()发送数据。
*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=newDatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)
四、Android实现socket简单通信
添加权限
--允许应用程序改变网络状态-->
name="android.permission.CHANGE_NETWORK_STATE"/> --允许应用程序改变WIFI连接状态--> name="android.permission.CHANGE_WIFI_STATE"/> --允许应用程序访问有关的网络信息--> name="android.permission.ACCESS_NETWORK_STATE"/> --允许应用程序访问WIFI网卡的网络信息--> name="android.permission.ACCESS_WIFI_STATE"/> --允许应用程序完全使用网络--> name="android.permission.INTERNET"/> 4.1使用TCP协议通信 Client端实现: 1. protected void connectServerWithTCPSocket() { 2. 3. Socket socket; 4. try {// 创建一个Socket对象,并指定服务端的IP及端口号 5. socket = new Socket("192.168.1.32", 1989); 6. // 创建一个InputStream用户读取要发送的文件。 7. InputStream inputStream = new FileInputStream("e: //a.txt"); 8. // 获取Socket的OutputStream对象用于发送数据。 9. OutputStream outputStream = socket.getOutputStream(); 10. // 创建一个byte类型的buffer字节数组,用于存放读取的本地文件 11. byte buffer[] = new byte[4 * 1024]; 12. int temp = 0; 13. // 循环读取文件 14. while ((temp = inputStream.read(buffer)) ! = -1) { 15. // 把数据写入到OuputStream对象中 16. outputStream.write(buffer, 0, temp); 17. } 18. // 发送读取的数据到服务端 19. outputStream.flush(); 20. } catch (UnknownHostException e) { 21. e.printStackTrace(); 22. } catch (IOException e) { 23. e.printStackTrace(); 24. } 25. 26. } Server端实现: 1.public void ServerReceviedByTcp() { 2. // 声明一个ServerSocket对象 3. ServerSocket serverSocket = null; 4. try { 5. // 创建一个ServerSocket对象,并让这个Socket在1989端口监听 6. serverSocket = new ServerSocket(1989); 7. // 调用ServerSocket的accept()方法,接受客户端所发送的请求, 8. // 如果客户端没有发送数据,那么该线程就停滞不继续 9. Socket socket = serverSocket.accept(); 10. // 从Socket当中得到InputStream对象 11. InputStream inputStream = socket.getInputStream(); 12. byte buffer[] = new byte[1024 * 4]; 13. int temp = 0; 14. // 从InputStream当中读取客户端所发送的数据 15. while ((temp = inputStream.read(buffer)) ! = -1) { 16. System.out.println(new String(buffer, 0, temp)); 17. } 18. serverSocket.close(); 19. } catch (IOException e) { 20. e.printStackTrace(); 21. } 22.} 4.2使用UDP协议通信 Client端实现: 1.protected void connectServerWithUDPSocket() { 2. 3. DatagramSocket socket; 4. try { 5.//创建DatagramSocket对象并指定一个端口号,注意,如果客户端需要接收服务器的返回数据, 6. //还需要使用这个端口号来receive,所以一定要记住 7. socket = new DatagramSocket(1985); 8. //使用InetAddress(Inet4Address).getByName把IP地址转换为网络地址 9. InetAddress serverAddress = InetAddress.getByName("192.168.1.32"); 10. 11. String str = "[2143213;21343fjks;213]";//设置要发送的报文 12. byte data[] = str.getBytes();//把字符串str字符串转换为字节数组 13. //创建一个DatagramPacket对象,用于发送数据。 14. //参数一: 要发送的数据 参数二: 数据的长度 参数三: 服务端的网络地址 参数四: 服务器端端口号 15. DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025); 16. socket.send(packet);//把数据发送到服务端。 17. } catch (SocketException e) { 18. e.printStackTrace(); 19. } catch (UnknownHostException e) { 20. e.printStackTrace(); 21. } catch (IOException e) { 22. e.printStackTrace(); 23. } 24.} Theclientreceivesthedatareturnedbytheserver 1.public void ReceiveServerSocketData() { 2. DatagramSocket socket; 3. try { 4. //实例化的端口号要和发送时的socket一致,否则收不到data 5. socket = new DatagramSocket(1985); 6. byte data[] = new byte[4 * 1024]; 7. //参数一: 要接受的data 参数二: data的长度 8. DatagramPacket packet = new DatagramPacket(data, data.length); 9. socket.receive(packet); 10. //把接收到的data转换为String字符串 11. String result = new String(packet.getData(), packet.getOffset(), 12. packet.getLength()); 13. socket.close();//不使用了记得要关闭 14. System.out.println("the number of reveived Socket is : " + flag 15. + "udpData: " + result); 16. } catch (SocketException e) { 17. e.printStackTrace(); 18. } catch (IOException e) { 19. e.printStackTrace(); 20. } 21.} Theserverreceivesthedatareturnedbytheclient [java] viewplaincopy 1.public void ServerReceviedByUdp(){ 2. //创建一个DatagramSocket对象,并指定监听端口。 (UDP使用DatagramSocket) 3. DatagramSocket socket; 4. try { 5. socket = new DatagramSocket(10025); 6. //创建一个byte类型的数组,用于存放接收到得数据 7. byte data[] = new byte[4*1024]; 8. //创建一个DatagramPacket对象,并指定DatagramPacket对象的大小 9. DatagramPacket packet = new DatagramPacket(data,data.length); 10. //读取接收到得数据 11. socket.receive(packet); 12. //把客户端发送的数据转换为字符串。 13. //使用三个参数的String方法。 参数一: 数据包 参数二: 起始位置 参数三: 数据包长 14. String result = new String(packet.getData(),packet.getOffset() ,packet.getLength()); 15. } catch (SocketException e) { 16. e.printStackTrace(); 17. } catch (IOException e) { 18. e.printStackTrace(); 19. } 20.} 五、UDP广播与多播 使用UDP协议进行信息的传输之前不需要建议连接。 换句话说就是客户端向服务器发送信息,客户端只需要给出服务器的ip地址和端口号,然后将信息封装到一个待发送的报文中并且发送出去。 至于服务器端是否存在,或者能否收到该报文,客户端根本不用管。 通常我们讨论的udp的程序都是一对一的单播程序。 本章将讨论一对多的服务: 广播(broadcast)、多播(multicast)。 对于广播,网络中的所有主机都会接收一份数据副本。 对于多播,消息只是发送到一个多播地址,网络知识将数据分发给哪些表示想要接收发送到该多播地址的数据的主机。 总得来说,只有UDP套接字允许广播或多播。 UDP广播 广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机。 值得强调的是: 本地广播信息是不会被路由器转发。 当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。 这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制。 广播地址通常用于在网络游戏中处于同一本地网络的玩家之间交流状态信息等。 广播就不在写演示程序了,读者可以将ECHO程序的ip地址改为广播地址即可。 其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。 UDP多播 同样的UDP多播也要指明接受者的端口号,而且与广播相似的是多播与单播之间的区别还在于地址。 ipv4中的多播地址范围是: 224.0.0.0到239.255.255.255。 在JAVA中,多播一样十分好实现,要实现多播,就要用到MulticastSocket类,其实该类就是DatagramSocket的子类,在使用时除了多播自己的一些特性外,把它当做DatagramSocket类使用就可以了。 XX地图 覆盖物Class 起点和终点图标替换 两点之间距离计算 定位优先级 Android资料 Debug模式 Log五种输出方式 工程测试模式 Apk是否已签名 Apk信息查看 资源目录Res 屏幕分辨率适配 精确适配不同的dpi和屏幕尺寸 一、引言 Android的开源使厂商无需自行研发OS,大大降低了研发、生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望。 与此同时带来的是广大开发者的苦不堪言,各种神奇的小板儿考验着app的兼容性,各种定制的rom不经意间就让app崩溃,光是界面上的调整就已经够你喝一壶了,是不? 二、适配可行性 早在Android设计之初就考虑到了这一点,为了让app适应标准or山寨屏幕,google已经有一套成熟的解决方案。 其中,有这么几个指标需要注意: (1)屏幕尺寸: 单位inch,指的是屏幕对角线长度。 (2)屏幕密度: 单位dpi,指的是每inch上可以显示多少像素点即px。 (3)屏幕分辨率: 单位px*px,指的是一屏显示多少像素点。 (4)屏幕无关像素: 单位dp/dip,指的是自适应屏幕密度的像素,用于指定控件宽高。 (5)刻度无关像素: 单位sp,指的是自适应字体的像素,用于指定文字大小。 以我自己的HaierW910超级战舰(宽高比16: 9)为例,上述单位的换算如下: 已知数据: 屏幕尺寸4.5,分辨率1280*720,屏幕密度320 (1)16: 9的4.5寸屏幕由勾股定理计算其高约为3.9寸,宽约为2.2寸 (2)则竖向dpi为1280/3.9≈328,横向dpi为720/2.2≈327 (3)工业上切割液晶板时取整为320 那么既然dpi是自适应屏幕密度的,与px之间又是如何换算呢: 120dpi(ldpi低密度屏) 1dp=0.75px (由于像素点是物理点,所以用2个像素点来显示3个dp的内容) 160dpi(mdpi中密度屏) 1dp=1px 213dpi(tvdpi电视密度屏) 1dp=1.33px 240dpi(hdpi高密度屏) 1dp=1.5px 320dpi(xhdpi极高密度屏) 1dp=2px 由上述分析结果可知,控件使用dp,文字使用sp即可满足自适应的需求。 三、适配方案 根据目前的调查,在市面上的平板,基本上属于mdpi和hdpi的,少数属于tvdpi(如google出的nexus7),所以我们选择这三种密度考虑适配;此外手机应用大多数都是竖屏使用,但平板作为娱乐性的一款产品,横竖屏均有使用的时候,所以我们还需要考虑到屏幕状态进行适配;最后考虑到有的rom会将虚拟键计算到屏幕尺寸里,还要考虑到虚拟键所占用的长宽。 那么如何根据这三个属性来进行适配呢? Android在资源文件values用文件名的方式提供了限定符可以帮助我们判断上述情况,限定符(mdpi,tvdpi,hdpi)可以帮助我们判断屏幕密度,限定符(land,port)可以帮助我们区分屏幕横竖屏状态,而限定符(1024x600...)可以适配计算虚拟键或者不计算虚拟键的屏幕,限定符的详细说明请参见AndroidSDK文档中开发者指南的SupportingMultipleScreens话题。 最终适配文件夹如下图所示: 注1: 分辨率限定符的匹配是向下匹
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 资料 分析