美文网首页
第 10 章 看看精彩的世界,使用网络技术

第 10 章 看看精彩的世界,使用网络技术

作者: wyxjoker | 来源:发表于2016-02-23 00:58 被阅读0次

    WebView的用法

    基础用法很简单..

    webView = (WebView) findViewById(R.id.web_view);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new WebViewClient() {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, Stringurl) {
        view.loadUrl(url); // 根据传入的参数再去加载新的网页
        return true; // 表示当前WebView可以处理打开新网页的请求,不用借助系统浏览器
      }
     });
    webView.loadUrl("http://www.baidu.com");
    

    网络访问需要权限:

    android.permission.INTERNET

    10.2使用HTTP协议访问网络

    Android中发送HTTP请求一般通过HttpURLConnection和HttpClient.

    首先需要获取到 HttpURLConnection 的实例,一般只需 new 出一个 URL 对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可.

    URL url = new URL("http://www.baidu.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    获取HttpURLConnection实例后设置HTTP请求方法,常用是是Get和Post.Get表示获取数据,Post表示提数据.

    connection.setRequestMethod("GET");

    之后就可以设置连接超时,读取超时的毫秒数或者服务器希望得到的消息头等.
    在调用getInputStream()就可以获得服务器返回的输入流.

    InputStream in = connection.getInputStream();

    最后可以调用disconnect()关闭该HTTP连接.

    Post示例:

    connection.setRequestMethod("POST");
    DataOutputStream out = new DataOutputStream(connection.getOutputStream());
    out.writeBytes("username=admin&password=123456");

    10.2.2 使用HttpClient

    Android6.0后已废弃.

    10.3解析XML格式数据

    10.3.1Pull解析方式

    private void parseXMLWithPull(String xmlData) {
      try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser xmlPullParser = factory.newPullParser();
        xmlPullParser.setInput(new StringReader(xmlData));
        int eventType = xmlPullParser.getEventType();
        String id = "";
        String name = "";
        String version = "";
        while (eventType != XmlPullParser.END_DOCUMENT) {
          String nodeName = xmlPullParser.getName();
           switch (eventType) {
              // 开始解析某个结点
            case XmlPullParser.START_TAG: {
              if ("id".equals(nodeName)) {
                id = xmlPullParser.nextText();
              } else if ("name".equals(nodeName)) {
                name = xmlPullParser.nextText();
              } else if ("version".equals(nodeName)) {
                version = xmlPullParser.nextText();
              }
              break;
             }
            // 完成解析某个结点
            case XmlPullParser.END_TAG: {
              if ("app".equals(nodeName)) {
                Log.d("MainActivity", "id is " + id);
                Log.d("MainActivity", "name is " + name);
                Log.d("MainActivity", "version is " + version);
              }
              break;
            }
            default:
              break;
          }
          eventType = xmlPullParser.next();
        }
       } catch (Exception e) {
        e.printStackTrace();
       }
    }
    

    获取的数据不对(sad脸

    10.3.2SAX解析方式

    新建一个类继承DefaultHandle,重写startDocument(),startElement(),characters(),endElement(),endDocument()五个方法.

    • startDocument()方法会在开始 XML 解析的时候调用.
    • startElement()方法会在开始解析某个结点的时候调用.
    • characters()方法会在获取结点中内容的时候调用.
    • endElement()方法会在完成解析某个结点的时候调用.
    • endDocument()方法会在完成整个 XML 解析的时候调用.

    其中, startElement()、 characters()和 endElement()这三个方法是有参数的,从 XML 中解析出的数据就会以参数的形式传入到这些方法中。需要注意的是,在获取结点中的内容时, characters()方法可能会被调用多次,一些换行符也被当作内容解析出来,我们需要针对这种情况在代码中做好控制
    示例:

    public class ContentHandler extends DefaultHandler {
      private String nodeName;
      private StringBuilder id;
      private StringBuilder name;
      private StringBuilder version;
      @Override
      public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
      }
      @Override
      public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
        // 记录当前结点名
        nodeName = localName;
      }
      @Override
      public void characters(char[] ch, int start, int length)   throwsSAXException {
        // 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
        if ("id".equals(nodeName)) {
          id.append(ch, start, length);
        } else if ("name".equals(nodeName)) {
          name.append(ch, start, length);
        } else if ("version".equals(nodeName)) {
          version.append(ch, start, length);
        }
      }
      @Override
      public void endElement(String uri, String localName, String   qName) throwsSAXException {
        if ("app".equals(localName)) {
          Log.d("ContentHandler", "id is " + id.toString().trim());
          Log.d("ContentHandler", "name is " + name.toString().trim());
          Log.d("ContentHandler", "version is " +     version.toString().trim());
        // 最后要将StringBuilder清空掉id.setLength(0);
          name.setLength(0);
          version.setLength(0);
        }
      }
      @Override
      public void endDocument() throws SAXException {
      }
    }
    
    private void parseXMLWithSAX(String xmlData) {
      try {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        XMLReader xmlReader =   factory.newSAXParser().getXMLReader();
        ContentHandler handler = new ContentHandler();
        // 将ContentHandler的实例设置到XMLReader中  
        xmlReader.setContentHandler(handler);
        // 开始执行解析
        xmlReader.parse(new InputSource(new   StringReader(xmlData)));
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    

    10.4解析JSON格式数据

    JSON相对于xml体积更小,但是语义较差,没xml直观.解析JSON可以使用官方提供的 JSONObject,也可以使用谷歌的开源库 GSON。或者第三方的开源库如 Jackson、 FastJSON .

    10.4.1使用JSONObject

    10.4.2使用GSON

    新建类,包含标签.

    public class App {
      private String id;
      private String name;
      private String version;
      public String getId() {
        return id;
      }
      public void setId(String id) {
        this.id = id;
      }
      public String getName() {
        return name;
      }
      public void setName(String name) {
        this.name = name;
      }
      public String getVersion() {
        return version;
      }
      public void setVersion(String version) {
        this.version = version;
      }
    }
    

    使用方法:

    private void parseJSONWithGSON(String jsonData) {
      Gson gson = new Gson();
      List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>() {}.getType());
      for (App app : appList) {
        Log.d("MainActivity", "id is " + app.getId());
        Log.d("MainActivity", "name is " + app.getName());
        Log.d("MainActivity", "version is " + app.getVersion());
      }
    }
    

    10.5 网络编程的最佳实践

    可以把所有的网络操作提取到一个公共的类中,并提供静态方法.
    网络请求通常都是属于耗时操作,而 sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用 sendHttpRequest()方法的时候使得主线程被阻塞住。若开启线程,则sendHttpRequest()会在服务器相应前执行结束而无法返回相应的数据.组要使用回调机制.
    例如:
    定义接口:

    public interface HttpCallbackListener {
      void onFinish(String response);
      void onError(Exception e);
    }
    

    实现接口:

    public class HttpUtil {
      public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
          @Override
          public void run() {
            HttpURLConnection connection = null;
            try {
              URL url = new URL(address);
              connection = (HttpURLConnection) url.openConnection();
              connection.setRequestMethod("GET");
              connection.setConnectTimeout(8000);
              connection.setReadTimeout(8000);
              connection.setDoInput(true);
              connection.setDoOutput(true);
              InputStream in = connection.getInputStream();
              BufferedReader reader = new       BufferedReader(newInputStreamReader(in));
              StringBuilder response = new StringBuilder();
              String line;
              while ((line = reader.readLine()) != null) {
                response.append(line);
              }
              if (listener != null) {
                // 回调onFinish()方法
                listener.onFinish(response.toString());
              }
            } catch (Exception e) {
              if (listener != null) {
                //回调onError()方法
                listener.onError(e);
              }
            } finally {
              if (connection != null) {
                connection.disconnect();
              }
            }
          }
        }).start();
      }
    }
    

    需要发起HTTP请求时:

    String address = "http://www.baidu.com";
    String response = HttpUtil.sendHttpRequest(address);
    

    相关文章

      网友评论

          本文标题:第 10 章 看看精彩的世界,使用网络技术

          本文链接:https://www.haomeiwen.com/subject/opbvkttx.html