Android学习笔记之网络编程及Internet应用


一、通过HTTP访问网络

在Android中,针对HTTP进行网络通信的方法主要有两种:一种是使用HttpURLConnection实现;另一种是使用HttpClient实现。

1.使用HttpURLConnection访问网络

HttpURLConnection类位于java.net包中,用于发送HTTP请求和获取HTTP响应。由于该类是抽象类,不能直接实例化对象,则需要使用URL的openConnection()方法来获得。

eg.

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

HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();

说明:通过openConnection()方法创建的HttpURLConnection对象,并没有真正执行连接操作,只是创建了一个新的实例,在进行链接前,还可以设置一些属性。例如,连接超时的时间和请求方式等。

创建了HttpURLConnection对象后,就可以使用该对象发送HTTP请求了。HTTP请求通常分为GET请求和POST请求两种。

1)发送GET请求

使用HttpURLConnection对象发送请求时,默认发送的就是GET请求。因此,发送GET请求比较简单,只需要在指定连接地址时,先将要传递的参数通过“?参数名=参数值”进行传递(多个参数间使用英文半角的逗号分隔。例如,?user=wgh,email=wgh717@shouhu.com),然后获取流中的数据,并关闭连接即可。

eg.

public void send(){

    String target="";

    target="http://192.168.1.66:8081/blog/index.jsp?content="+base64(content.getText().toString().trim());

    URL url;

     try{

         url=new URL(target);

         HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();


         InputStreamReader in = new InputStreamReader(urlConn.getInputStream());

         BufferedReader buffer = new BufferedReader(in);

         String inputLine=null;

         while((inputLine=buffer.readLien())!=null){

             result+=inputLine+"\n";

         }

         in.close();

         urlConn.disconnect();

     }catch(MalformedURLExceotion e){e.printStackTrace();}

      catch(IOException e){e.printStackTrace();}

}

在应用GET方法传递中文的参数时,会产生乱码,这时可以进行Base64编码来解决乱码问题,为此,需要编写一个base64()方法,对要进行传递的参数进行Base64编码。

public String base64(String content){

    try{

        content = Base64.encodeToString(content.getBytes("utf-8"),Base64.DEFAULT);

        content=URLEcoder.encode(content);

    }catch(UnsupportedEncodingException e){

       e.printStackTrace

    }

    return content;

}

要解决应用GET方法传递中文参数时产生乱码的问题,也可以使用Java提供的URLEncoder类来实现。

2)发送POST请求

由于采用GET方式发送请求只适合发送大小在1024个字节以内的数据,所以当要发送的数据较大时,就需要使用POST方式来发送请求。在Android中,使用HttpURLConnection类发送请求时,默认采用的是GET请求,如果要发送POST请求,需要通过其setRequestMethod()方法进行指定。

eg.

HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();

urlConn.setRequestMethode("POST");

发送POST请求要比发送GET请求复杂一些,它经常需要通过HttpURLConneciton类及其父类URLConneciton提供的方法设置相关内容。

发送POST请求常用的方法:

setDoInput(boolean new Value)

setDoOutput(boolean new Value)

setUseCaches(boolean new Value)

setInstanceFollowRedirects(boolean followRedirects)

setRequestProperty(String field,String new Value)



2.使用HttpClient访问网络

HttpClient实际上是对Java提供的访问网络的方法进行了封装。HttpURLConnection类中的输入/输出流操作,在HttpClient中被封装成了HttpGet、HttpPost和HttpResponse类,这样,就简化了操作。其中,HttpGet类代表发送GET请求;HttpPost类代表发送POST请求;HttpResponse类代表处理响应的对象。

1)发送GET请求

①创建HttpClient对象

②创建HttpGet对象

③如果需要发送请求参数,可以直接将要发送的参数连接到URL地址中,也可以调用HttpGet的setParams()方法来添加请求参数。

④调用HttpClient对象的execute()方法发送请求。执行该方法将返回一个HttpResponse对象。

⑤调用HttpResponse的getEntity()方法,可获得包含服务器响应内容的HttpEntity对象,通过该对象可以获取服务器的相应内容。

eg.

public void send(){

    String target="http://192.168.1.66:8081/blog/deal_httpclient.jsp?param=get";

    HttpClient httpclient = new DefaultHttpClient();

    HttpGet httpRequest = new HttpGet(target);

    HttpResponse httpResponse;

    try{

     httpResponse = httpClient.execute(httpRequest);

     if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){

        result = EntityUtils.toString(httpResponse.getEntity());

     }else{

         result="请求失败!";

     }

    }catch(ClientProtocolException e){e.printStackTrace();}

    catch(IOException e){e.printStackTrace();}

}

2)发送POST请求

①创建HttpClient对象

②创建HttpPost对象

③如果需要发送请求参数,可以调用HttpPost的setParams()方法来添加请求参数,也可以调用setEntity(0方法来设置请求参数。

④调用HttpClient对象的execute()方法发送请求。执行该方法将返回一个HttpResponse对象。

⑤调用HttpResponse的getEntity()方法,可获得包含服务器响应内容的HttpEntity对象,通过该对象可以获取服务器的响应内容。

eg.

public void send(){

    String target="http://192.168.1.66:8081/blog/deal_httpclient.jsp";

   HttpClient httpclient = new DefaultHttpClient();

   HttpPost httpclient = new HttpPost(target);

   List<NameValuePair> params = new ArrayList<NameValuePair>();

   params.add(new BasicNameValuePair("param","post");

   params.add(new BasicNameValuePair("nickname","nickename");

   params.add(new BasicNameValuePair("content","content");

   try{

       httpRequest.setEntity(new UrlEncodedFormEntity(params,"utf-8"));

       HttpResponse httpResponse = httpClient.execute(httpRequest);

       if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){

           result+=EntityUtils.toString(httpResponse.getEntity());

       }else{rusult="请求失败!";}

   }catch(UnsupportedEncodingException e1){e1.printStackTrace();}

   catch(ClientProtocolException e){e.printStackTrace();}

   catch(IOException e){e.printStackTrace();}

}


不过由于HttpClient存在API数量过多、扩展困难等缺点,Android团队越来越不建议我们使用这种方式,终于在Android6.0系统中,HttpClient的功能被完全移除了,标志着此功能被正式弃用,现在官方建议使用HttpURLConnection的用法。


3.使用OkHttp

OkHttp是由鼎鼎大名的Square公司开发的,这个公司在开源事业上面贡献良多,除了OkHttp之外,还开发了像Picasso、Retrofit等著名的开源项目。

在使用OkHttp之前,我们需要现在项目中添加OkHttp库的依赖。编辑app/build.gradle文件,在dependencies闭包中添加如下内容:

dependencies{

    compile fileTree(dir:'libs',include:['*.jar'])

    compile 'com.android.support:appcompat-v7:24.2.1'

    testCompile 'junit:junit:4.12'

    compile 'com.squareup.okhttp3:okhttp;3.4.1‘

}

添加上述依赖会自动下载两个库,一个是OkHttp库,一个是Okio库,后者是前者的通信基础。

OkHttp具体用法:

①创建一个OkHttpClient的实例:OkHttpClient client = new OkHttpClient();

②创建一个Request对象:Request request = new Request.Builder().build();

eg.

Request request=new Request.Builder().url("http://www.bbaidu.com").build();

③调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据:

Response response = client.newCall(request).execute();

其中Response对象就是服务器返回的数据了,可以使用如下写法得到返回的具体内容:

String responseData = response.body().string();

如果是发起一条POST请求,需要先构建出一个RequestBody对象来存放待提交的参数,如下所示:

RequestBody requestBody = new FormBody.Builder().add("username","admin").add("password","123456").build();

然后在Request.Builder中调用一下post()方法,并将RequestBody对象传入:

Request request = new Request.Builder().url("http://www.baidu.com").post(requestBody).build();

接下来的操作就和GET请求一样了,调用execute()方法来发送请求并获取服务器返回的数据即可。


网络编程最佳实践

通常情况下我们应该将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法,当想要发起网络请求的时候,只需简单调用一下这个方法即可。

eg.

public class HttpUtil{

    public static String sendHttpRequest(String address){

        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(new InputStreamReader(in));

            StringBuilder response = new StringBuilder();

            String line;

            while((line=reader.readLine())!=null){

                response.append(line);

             }

             return response.toString();

         }catch(Exception e){

             e.printStackTrace();

             return e.getMessage();

         }

         finally{

             if(connection!=null){connection.disconnect();}

         }

    }

}

发起请求时如下:

String address="http://www.baidu.com";

String response = HttpUtil.sendHttpRequest(address);


优化如下:

首先定义一个接口,命名为 HttpCallbackListener,代码如下

public interface HttpCallbackListener{

    void onFinish(String response);

    void onError(Exception e);

}

我们在接口中定义了两个方法,onFinish()方法表示当服务器成功响应我们请求的时候调用,onError()表示当进行网络操作出现错误的时候调用。这两个方法都带有参数,onFinish()方法中的参数代表着服务器返回的数据,而onError()方法中的参数记录着错误的详细信息。

public class HttpUtil{

    public static void sendHttpRequest(final String address,final HttpCallbackListener listener){

        new Thread(new Runnable(){

            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(new InputStreamReader(in));

                    StringBuilder response = new StringBuilder();

                    String line;

                    while((line=reader.readLine())!=null){

                        response.append(line);

                    }


                    if(listener!=null){

                       listener.onFinish(response.toString());

                    }

                }catch(Exception e){

                    if(listener!=null){

                       listener.onError(e);

                     }

                }finally{

                    if(connection!=null){

                        connection.disconnect();

                     }

                }

            }

        }).start();

    }

}

我们首先给sendHttpRequest()方法添加一个HttpCallbackListener参数,并在方法的内部开启了一个子线程,然后在子线程里去执行具体的网络操作。注意,子线程中时无法通过return语句来返回数据的,因此这里我们将服务器响应的数据传入了HttpCallbackListener的onFinish()方法中,如果出现了异常就将异常原因传入到onError()方法中。

调用上述网络请求方法如下:

HttpUtil.sendHttpRequest(address,new HttpCallbackListener(){

    public void onFinish(String response){

        //在这里根据返回的内容执行具体的逻辑操作

    }

  

   public void onError(Exception e){

       //在这里对异常情况进行处理

   }

});


使用OkHttp构建网络请求类如下:

public class HttpUtil{

    ...


    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){

        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder().url(address).build();

        client.newCall(request).enqueue(callback);

    }


}

我们在调用sendOkHttpRequest()方法时如下:

 HttpUtil。sendOkHttpRequest(“http://www.baidu.com”,new okhttp3.Callback(){

        public void onResponse(Call call,Response response) throws IOException{

             //得到服务器返回的具体内容

            String responseData = response.body().string();

        }


        public voidd onFailure(Call call,IOException e){

            //在这里对异常情况进行处理

        }

    });

另外需要注意的时,不管是使用HttpURLConnection还是OkHttp,最终的回调接口都还是在子线程中运行的,因此我们不可以在这里执行任何的UI操作,除非借助runOnUiThread()方法来进行线程转换。


二、使用Webview显示网页

1.使用WebView组件浏览网页

2.使用WebView加载HTML代码

3.让WebView支持JavaScript

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值