android重新学_网络2——采用HttpURLConnection获取获取网页源代码
本文是android应用开发_网络部分1——采用HttpURLConnection获取网络图片的延续练习。
接下来,我们再来一个查看网页源代码的工程来加深了解。
布局上还是一个竖直排列的线性布局,一个edittext用于输入html路径,一个button,用于点击获取,一个textview用于显示。
main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 8 <EditText android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:id="@+id/et_path"/> 11 <Button android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:text="查看" 14 android:id="@+id/btn_get"/> 15 <TextView 16 android:layout_width="fill_parent" 17 android:layout_height="wrap_content" 18 android:layout_weight="1" 19 android:id="@+id/text_html" 20 android:text="" 21 /> 22 </LinearLayout>
因为是接着上篇继续写的,所以与上篇大体相同的代码,就不再写注释了。
MyActivity.java
1 package com.example.getHtmlSrc; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Message; 7 import android.view.View; 8 import android.widget.EditText; 9 import android.widget.TextView; 10 import android.widget.Toast; 11 12 import java.io.ByteArrayOutputStream; 13 import java.io.IOException; 14 import java.io.InputStream; 15 import java.net.HttpURLConnection; 16 import java.net.URL; 17 18 public class MyActivity extends Activity { 19 20 Handler handler; 21 final static int MESSAGE_REQUEST_ERR = 0; 22 final static int MESSAGE_SHOW_CONTENT = 1; 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main); 27 ((EditText)findViewById(R.id.et_path)).setText("https://www.baidu.com/"); 28 29 handler = new Handler() { 30 @Override 31 public void handleMessage(Message msg) { 32 // super.handleMessage(msg); 33 switch (msg.what){ 34 case MESSAGE_REQUEST_ERR : 35 Toast.makeText(MyActivity.this,"获取失败",Toast.LENGTH_SHORT).show(); 36 break; 37 case MESSAGE_SHOW_CONTENT: 38 ((TextView)findViewById(R.id.text_html)).setText((String)msg.obj); 39 break; 40 } 41 } 42 }; 43 44 findViewById(R.id.et_path).setOnClickListener(new View.OnClickListener() { 45 @Override 46 public void onClick(View v) { 47 String path = ((EditText) findViewById(R.id.et_path)).getText().toString().trim(); 48 newThreadToGet(path); 49 } 50 }); 51 } 52 53 private void newThreadToGet(String path) { 54 new Thread(){ 55 @Override 56 public void run() { 57 //super.run(); 58 getHtmlContent(path); 59 } 60 }.start(); 61 } 62 63 private void getHtmlContent(String path) { 64 try { 65 URL url = new URL(path); 66 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 67 connection.setRequestMethod("GET"); 68 connection.setConnectTimeout(5000); 69 //connection.setRequestProperty(); 70 //connection.setReadTimeout(60000); 71 int code = connection.getResponseCode(); 72 if(code == 200){ 73 /* 74 * 获取成功,服务器返回输入流 75 * 接下来就需要将输入流转化成字符串 76 * 赋值给textview,显示出来 77 * */ 78 String content = convertToString(connection.getInputStream()); 79 Message message = new Message(); 80 if(content != null ){ 81 message.what = MESSAGE_SHOW_CONTENT; 82 message.obj = content; 83 84 } else { 85 message.what = MESSAGE_REQUEST_ERR; 86 } 87 handler.sendMessage(message); 88 } else { 89 Message message = new Message(); 90 message.what = MESSAGE_REQUEST_ERR; 91 handler.sendMessage(message); 92 } 93 } catch (Exception e) { 94 e.printStackTrace(); 95 Message message = new Message(); 96 message.what = MESSAGE_REQUEST_ERR; 97 handler.sendMessage(message); 98 } 99 } 100 101 private String convertToString(InputStream inputStream) { 102 /* 103 * 思路:我们可以定义出一个内存输出流。 104 * 把InputStream里面的内容全部都写入到内存输出流里, 105 * 然后再把内存输出流里的数据转化成字符串。 106 * */ 107 try { 108 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 109 int len = 0; 110 byte[] buffer = new byte[1024]; 111 112 /* 113 * 接下来我们就循环的读取InputStream里面的内容,写入到baos中。 114 * 把InputStream内容读到buffer里面, 115 * 究竟读了多长呢?返回一个值赋给len, 116 * 如果他没有读到流的末尾返回值不会等于-1, 117 * 将这个作为条件,添加一个while循环,循环里面,只要没有读到末尾, 118 * baos就要调用write()的方法,把buffer里面的内容从0写到len. 119 * */ 120 121 while((len=inputStream.read(buffer))!=-1){ 122 baos.write(buffer,0,len); 123 } 124 //关流,内存输入流不需要close 125 inputStream.close(); 126 /* 127 * return new String(baos.toByteArray()); 128 * 我们直接newstring,在android下系统默认的default charset是utf8, 129 * 所以,我们直接new String(result); 130 * 就相当于new String(result,”utf-8”); 131 * 而这样就把代码写死了。如果有非utf8格式的内容,就会出现中文乱码 132 * */ 133 134 /* 135 * 在解析一个网页的时候,一般都会有<meta>的头部信息, 136 * 在这里会有一个charset属性,指明了网页所使用的编码, 137 * 因为是英文和数字组合,所以在任何编码集下都不会乱码。 138 * 所以,我们可以在转换成字符串之前,解析一下里面的内容, 139 * 规范一些的话,我们应该是利用正则表达式,去匹配, 140 * 里面以meta开头的,后面以>结尾的,再匹配里面的数字 141 * */ 142 143 /* 144 * 这里我们只是简单的进行字符串匹配处理。 145 * 以此作为条件进行ifelse的判断 146 * */ 147 148 String temp = new String(baos.toByteArray()); 149 if (temp.contains("utf-8")){ 150 return temp; 151 } else if (temp.contains("gb2312")){ 152 return temp; 153 }else if (temp.contains("gbk")){ 154 return temp; 155 }else if (temp.contains("ISO8859-1")){ 156 return temp; 157 } 158 } catch (IOException e) { 159 e.printStackTrace(); 160 } 161 162 return null; 163 } 164 }
效果展示:
对于中文乱码问题还有一种判断方法,像我们常用的汉字,都是在码表里有对应的范围的,如果发现当前转化出来的这些文本都不在码表的范围里,假设”中国”,所对应的码表范围不在utf8中,那么他就会判断出来当前的网页的编码集很有可能不是utf8。
Android程序员在开发与服务器端进行交互的代码的时候,服务器端呢很可能是不能改了,已经固定下来了,在安卓端做处理的时候,就必须要去清楚服务器端所返回的数据编码,如果是utf8的,就不需要做任何处理了,如果是其他编码类型,就需要进行处理,将中文正确的显示出来