现在的位置: 首页 > 综合 > 正文

安卓学习第四天

2018年05月17日 ⁄ 综合 ⁄ 共 10972字 ⁄ 字号 评论关闭
ByteArrayOutputStream此类实现了一个输出流,
其中的数据被写入一个 byte 数组。
缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。 
它最大的作用就是缓冲。其实是把数据先写到内存里面了。其实是把流转换成byte数组
并且写到内存中。
/**
	 * 把一个inputstream里面的内容转化成一个byte[] 
	 * @throws IOException 
	 */
public static byte[] getBytes(InputStream inputStream) throws IOException{
	ByteArrayOutputStream bos = new ByteArrayOutputStream();
	byte[] buffer = new byte[1024];
	int len = 0;
	while((len = inputStream.read(buffer))!=-1){
		bos.write(buffer, 0, len);//其实是写到 了内存中。
	}
	inputStream.close();
	bos.close();
	byte[] resutl = bos.toByteArray();//如果你这这样写,内存会一直增加。
	System.out.println(new String(resutl));
	return resutl;
}

安卓上默认的是UTF-8.

初始化布局填充器的两种方法。。

你的资源性文件不能与JAVA中关键字重名,因为所有的资源性文件最终都会以R文件的内部类的形式作
为一个命名,如果你用了JAVA关键字,在这里生成相应的引用的时间会造成错误。这点切记 。

从今天开始,你必须要明白为什么人们把各种流转换成字节流,因为底层就是字节流,八位一个字节,
read()每次就是读取一个字节,也就是说JAVA读取的最基本单位都是字节,所以要把流转换成字节数组。
URL url = new URL(path);
url.openConnection();//这个方法返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。 
//每次调用此 URL 的协议处理程序的 openConnection 方法都打开一个新的连接。 
//也就是说,每次调用一次这个方法就访问一次path这个路径。那么从这个地址返回的数据流用
conn.getInputStream();接收。把流接收之后转换成字节数组流,其实就是一大群有序的字节,
然后new String(bytes);然后我们就得到了从流里面返回的字串,多么有逻辑的一个过程呀。

//知识点
android:layout_gravity是用来设置该view相对与起父view 的位置.
比如一个button 在linearlayout里,你想把该button放在靠左、靠右等位置就可以通过该属性设置.
以button为例,android:layout_gravity="right"则button靠右

//透析 GET提交 方式 。
1、首先在客户端,你想要发中文,还是以GET方式发的,只有一种可能,你必须要它进行URLEncoder,
//该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法只有这样才能够正常的发出去。
2、你能够正常发了,记住,所有的数据都必须要以0011的方式才能够提交,但是,你到了tomcat那里,tomcat默认的编码集
//是iso8859-1,它会以这种编码集对这些0011进行解码(详细的在下面),所以中文服务器要想正确的收也要设置,先让这些东西 
//转化成iso8859-1的字节数组,然后再对其用UTF-8编码不就行了。(再次加深理解了为什么一切都要转化为字节数组,因为JAVA
//读 写数据最基本的单位是一个字节)
客户端:
String u = URLEncoder.encode(username);
String p = URLEncoder.encode(password);
服务器:
String name = request.getParameter("username");
String password = request.getParameter("password");
name = new String(name.getBytes("iso8859-1"), "utf-8");
password = new String(password.getBytes("iso8859-1"), "utf-8");

至此,你已经了解了GET方式的精华。
	
//URLEncoder:详解。
对 String 编码时,使用以下规则: 
字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。 
特殊字符 "."、"-"、"*" 和 "_" 保持不变。 
空格字符 " " 转换为一个加号 "+"。 
所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。
然后每个字节用一个包含 3 个字符的字符串 "%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。
推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。 
例如,使用 UTF-8 编码机制,字符串 "The string ü@foo-bar" 将转换为 "The+string+%C3%BC%40foo-bar",
因为在 UTF-8 中,字符 ü 编码为两个字节,C3 (十六进制)和 BC (十六进制),字符 @ 编码为一个字节 40 (十六进制)。 
一个汉字按照UTF-8URL 之后会有三个,下面是中国的编码。

http://zh.wikipedia.org/zh/%E4%B8%AD%E5%9C%8B


http://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD

属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。
//iso8859-1详解。
很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。
但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,
仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,
虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应该是"d6d0 cec4"两个字符,
使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为单位处理的)。

//GEt POST的区别?
get一次提交数据量小,只能提交4K。内部其实是通过拼URL的方式。
POST不限制,且是以form表单的形式流提交给服务器的。


FUCK POST方式竟然也这么复杂。
服务器端:(POST与GET一样。)
String name = request.getParameter("username");
String password = request.getParameter("password");
response.getWriter().print(name + password + " ==");
if (name != null) {
	name = new String(name.getBytes("iso8859-1"), "utf-8");
}
if (password != null) {
	password = new String(password.getBytes("iso8859-1"), "utf-8");
}
System.out.println(name +"username");
System.out.println(password +"password");
response.setCharacterEncoding("utf-8");//这里这样设置,因为安卓默认是UTF-8编码,所以就这样了。
response.getWriter().print("登陆成功");

客户端:
/**
	 * 采用post的方式 提交数据到服务器
	 * 
	 * @param path
	 *            服务器servlet的地址
	 * @param name
	 *            用户名
	 * @param password
	 *            密码
	 * @return 服务器返回的数据信息
	 * @throws IOException 
	 * @throws Exception
	 */
	public static String sendDataByPost(String path,String username,String password) throws IOException{
		
		String u = URLEncoder.encode(username);
		String p = URLEncoder.encode(password);
		URL url = new URL(path);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		//发送的数据还要自己拼接,并且也要先转码application/x-www-form-urlencoded
		String data = "username=" + u + "&password=" + p;
		connection.setRequestMethod("POST");
		//将此 URLConnection 的 doOutput 字段的值设置为指定的值。
		connection.setDoOutput(true);
		connection.setDoInput(true);
		// 设置http协议的消息头 POST提交 方式 中两个 HTTP协议头必不可少
		connection.setRequestProperty("Content-Type",
		"application/x-www-form-urlencoded");
		connection.setRequestProperty("Content-Length", data.length() + "");
		// 把我们准备好的data数据写给服务器 因为post是以流的方式 写的。
		OutputStream os = connection.getOutputStream();
		os.write(data.getBytes());
		
		int code = connection.getResponseCode();
		if (code == 200) {
			InputStream inputStream = connection.getInputStream();
			byte[] bytes = StreamUtil.getBytes(inputStream);
			return new String(bytes);
		}else {
			throw new IllegalStateException("服务器状态异常");
		}
		
	}
	
Activity:
String u1 = username.getText().toString().trim();
String p1 = password.getText().toString().trim();
if (u1 == "" || p1 == "") {
	Toast.makeText(LoginActivity.this, "用户名或密码不能为空", Toast.LENGTH_LONG).show();
	return ;
}
//获取要访问的路径 
String path1 = getResources().getString(R.string.serverurl);
System.out.println(u1+p1+path1+"  ---");
try {
	String resString = DataService.sendDataByPost(path1, u1, p1);
	Toast.makeText(LoginActivity.this, resString, 0).show();
} catch (IOException e) {
	e.printStackTrace();
}

//以上是面向HTTP协议编程,用起来十分麻烦,而且容易引起问题。所以出现了HTTPClient.
httpclient 浏览器的简单包装 
new HttpClient 就相当于得到了一个浏览器 

具体参看代码。

//上传。
首先,你要会WEB的上传,WEB上传很简单,加入两个JAR包,然后在Servlet里面写上相应的代码,在JSP
里面写上一个file类型的。
<form action="/web/DemoServlet" method="post" enctype="multipart/form-data">
姓名<input name="name" value="" >
密码<input name="password" value="">
文件<input name="file" type="file">
提交<input type="submit" value="进入"/>
</form>

boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
	String realpath = request.getSession().getServletContext().getRealPath("/files");
	System.out.println(realpath);
	File dir = new File(realpath);
	if(!dir.exists()) dir.mkdirs();
	
	FileItemFactory factory = new DiskFileItemFactory();
	ServletFileUpload upload = new ServletFileUpload(factory);
	upload.setHeaderEncoding("UTF-8");
	try {
		List<FileItem> items = upload.parseRequest(request);
		for(FileItem item : items){
			if(item.isFormField()){
				 String name1 = item.getFieldName();//得到请求参数的名称
				 String value = item.getString("UTF-8");//得到参数值
				 System.out.println(name1+ "="+ value);
			}else{
				item.write(new File(dir, System.currentTimeMillis()+ item.getName().substring(item.getName().lastIndexOf("."))));
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}else{
	doGet(request, response);
}

然后就这样你就上传成功了。!!!!

开始移植安卓。
1,首先把安卓没有集成的HttpClientjar包给集成进去 。
2,写一个服务的方法,去发送并且接收数据。
3,在Activity中调用这个服务的方法。
/**
	 * 提交数据给服务器 带一个文件 
	 * @param path
	 * @param name
	 * @param password
	 * @param filepath 文件在手机上的路径 
	 * @return
	 * @throws Exception
	 */
	public  static String sendDataByHttpClientPost(String path , String name,String password ,String filepath) throws Exception{
		// 实例化上传数据的 数组  part []
		Part[] parts = {new StringPart("name", name), 
				  new StringPart("password", password), 
				  new FilePart("file", new File(filepath))};
		
		PostMethod filePost = new PostMethod(path);
		
	  
		filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
		org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
        client.getHttpConnectionManager().getParams()
          .setConnectionTimeout(5000);
		int status = client.executeMethod(filePost);
		if(status==200){
//			String result = filePost.getResponseBodyAsString();
//			System.out.println( filePost.getResponseCharSet());
			String result = new String(filePost.getResponseBodyAsString());
			String ha = new String ( result.getBytes("ISO-8859-1"),"UTF-8");
			System.out.println(ha);
			
			System.out.println("--"+ha);
			return ha;
		}
		else{
			throw new IllegalStateException("服务器状态异常");
		}
	}
	
	case R.id.fileupload:
			String filePathString  = filePath.getText().toString().trim();
			if ("".equals(filePathString)) {
				Toast.makeText(this, "路径不能为空", 0).show();
				return ;
			}
			try {
				String result = DataService.sendDataByHttpClientPost(getResources().getString(R.string.serverurl)
						,username.getText().toString().trim() ,
						password.getText().toString().trim(),
						filePathString);
				System.err.println(result +"hahahhaha");
				Toast.makeText(this, result, 0).show();
				System.out.println(new String( result.getBytes("iso8859-1"),"utf-8"));
			} catch (NotFoundException e) {
				Toast.makeText(this, "访问网路异常", 0).show();
				e.printStackTrace();
			} catch (Exception e) {
				Toast.makeText(this, "访问网路异常", 0).show();
				e.printStackTrace();
			}
			break;

这个东西有可能会出现乱码,自己要想好是在哪一层出错的。
并且理解tomcat服务器的编码方式。还有安卓自己的编码方式。



//webservice可以理解为任何提供数据的服务器。
例如我的手机想要调用WEB服务器里面某个类里面的
某个方法。就要用到soap肥皂协议
simple object access protocol

其实我们就是给这个网站提交我们的访问信息,然后它返回一个信息。
我们提交的是它想要的XML,得到的也是一个XML,再解析就是了。

核心代码。

package cn.itcast.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.R.integer;
import android.util.Xml;

public class QueryService {
	
	public static String getAddress(String number) throws Exception{
		InputStream  inputStream = QueryService.class.getClassLoader().getResourceAsStream("data.xml");
		byte[] bytes = StreamTool.getBytes(inputStream);
		String xml = new String(bytes);
		String postxml = xml.replace("$mobile", number);
		System.out.println(postxml);
		//其实就是把这个有我们输入号码的XML传给服务器,服务器会返回相应的值 。
		String res = sendDataByPost(postxml);
		System.out.println(res +" 结果。");
		return res;
	}
	
	/**
	 * 采用post的方式 提交数据到服务器
	 * 
	 * @param path
	 *            服务器servlet的地址
	 * @param name
	 *            用户名
	 * @param password
	 *            密码
	 * @return 服务器返回的数据信息
	 * @throws Exception 
	 * @throws Exception
	 */
	public static String sendDataByPost(String postxml) throws Exception{
		
		String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
		URL url = new URL(path);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		//发送的数据还要自己拼接,并且也要先转码application/x-www-form-urlencoded
		String data = postxml;
		connection.setRequestMethod("POST");
		//将此 URLConnection 的 doOutput 字段的值设置为指定的值。
		connection.setDoOutput(true);
		connection.setDoInput(true);
		// 设置http协议的消息头 POST提交 方式 中两个 HTTP协议头必不可少
		connection.setRequestProperty("Content-Type",
		"application/soap+xml;charset=utf-8");
		connection.setRequestProperty("Content-Length", data.length() + "");
		// 把我们准备好的data数据写给服务器 因为post是以流的方式 写的。
		OutputStream os = connection.getOutputStream();
		os.write(data.getBytes());
		
		int code = connection.getResponseCode();
		if (code == 200) {
			//其实这个流就是下面的数据, 我们解析这个XML即可得到想要的结果 。
 //<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"><getMobileCodeInfoResult>15136225969:河南 郑州 河南移动全球通卡</getMobileCodeInfoResult></getMobileCodeInfoResponse></soap:Body></soap:Envelope> 结果。

			InputStream inputStream = connection.getInputStream();
			String address = parseXml(inputStream);
			return new String(address);
		}else {
			throw new IllegalStateException("服务器状态异常");
		}
	}	
	
	public static String parseXml(InputStream inputStream) throws XmlPullParserException, IOException{
		XmlPullParser parser = Xml.newPullParser();
		parser.setInput(inputStream, "utf-8");
		int type = parser.getEventType();
		while (type != XmlPullParser.END_DOCUMENT) {
			switch (type) {
			case XmlPullParser.START_TAG:
				if ("getMobileCodeInfoResult".equals(parser.getName())) {
					return parser.nextText();
				}
				break;
			
			}
			
			
			type = parser.next();
			
		}
		return "没有找到";
	}

}

data.xml
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
      <mobileCode>$mobile</mobileCode>
      <userID></userID>
    </getMobileCodeInfo>
  </soap12:Body>
</soap12:Envelope>





















抱歉!评论已关闭.