第六章 使用网络技术

来源:互联网 发布:爱的算法 pdf 编辑:程序博客网 时间:2024/06/05 15:31

一、WebView的用法

        在xml布局文件中添加WebView控件,一般设置match_parent ;

        然后在对应的代码中使用findViewById()方法获取了WebView的实例,调用getSettings()方法可以设置一些浏览器的属性,再加载网页。代码如下:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_webview);        mWebView = (WebView) findViewById(R.id.web_view);        mWebView.getSettings().setJavaScriptEnabled(true);//用getSettings()方法可以设置浏览器属性,这里调用了setJavaScriptEnabled()方法让WebView支持JavaScript脚本        mWebView.loadUrl("http://www.baidu.com");  //加载网页(这种加载方式是要从app跳转到浏览器打开网页)mWebView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                mWebView.loadUrl("http://www.zhihu.com");      //根据传入的参数再去加载新的网页                return true;                                   //表示当前WebView可以处理打开新网页的请求,不用借助系统浏览器            }        });

        上面通过调用setWebViewClient()方法,并传入WebViewClient的匿名类作为参数,然后重写了shouldOverrideUrlLoading()方法。通过返回true,表明当需要从一个网页跳转到另一个网页时,目标网页直接在当前WebView中显示,而不是打开浏览器。

        这里使用了网络功能,所以要在mainfest中声明权限:

<uses-permission androdi:name = "android.permission.INTERNET"

        这里有一个问题,就是当我们点击返回时,会直接退出网页。而经常我们需要返回前一个浏览的网页,要怎么做到呢?设置网页可前后或后退的代码:

@Override    public void onBackPressed() {        if (mWebView != null && mWebView.canGoBack()) {  //如果mWebView不为空且可以回退            mWebView.goBack();                           //则点击返回时回到上一次的网页            mWebView.goForward();                        //前进功能            mWebView.reload();                           //重新加载,即刷新网页            mWebView.goBackOrForward(-1);                //控制可以前进或后退几步,负数表示后退,正数表示前进        }        else{            super.onBackPressed();                       //否则直接退出网页        }    }

二、HTTP请求

        HTTP协议的原理——客户端向服务器发出一条HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端会对数据进行解析和处理。

        对于上面学到的WebView控件,原理就是这样 —— 我们向百度服务器发送一条HTTP请求,接着服务器分析出我们要访问的是百度首页,于是把该网页的HTML代码进行返回,然后WebView再调用手机浏览器的内核对返回的HTML代码进行解析,最后将页面显示出来。也就是说,WebView中封装了发送HTTP请求、接收服务器响应、解析返回数据、以及最终的页面展示这几步功能。

        Android中发送HTTP请求有两种方式 —— HttpURLConnection 和 HttpClient。

    2.1 使用HttpURLConnection

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

URL url = new URL("www.baidu.com");HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        2. 设置HTTP请求所使用的方法,以及其他的一些自由的定制:

connection.setRequestMethod("GET");    //常用的方法有GET和POST两种,GET表示希望从服务器中获取数据,而POST表示希望发送数据给服务器connection.setConnectTimeout(30000);   //设置连接超时connection.setReadTimeout(30000);     //设置读取超时
        3. 调用getInputStream()方法获取服务器返回的输入流,剩下的任务就是对输入流进行读取;

以下是使用HttpURLConnection向http发送请求的完整代码:

public class test extends Activity implements View.OnClickListener {    public static final int SHOW_RESPONSE = 1;    private TextView mResponseText;    private Handler handler = new Handler() {        public void handleMessage(Message msg) {            switch (msg.what) {                case SHOW_RESPONSE:                    mResponseText.setText((String)msg.obj);            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button sendRequest = (Button) findViewById(R.id.button);        mResponseText = (TextView) findViewById(R.id.text);        sendRequest.setOnClickListener(this);    }    @Override    public void onClick(View v) {        if (v.getId() == R.id.button) {            sendRequestWithHttpURLConnection();        }    }    private void sendRequestWithHttpURLConnection() {        //开启线程来发起网络请求        new Thread(new Runnable() {            @Override            public void run() {                HttpURLConnection connection = null;                try {                    URL url = new URL("www.baidu.com");                    connection = (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("GET");                    connection.setConnectTimeout(30000);                    connection.setReadTimeout(30000);                    int responseCode = connection.getResponseCode();     //服务器返回的状态码                    InputStream inputStream = connection.getInputStream();                    //下面对获取的输入流进行读取                    if (responseCode == HttpURLConnection.HTTP_OK) {     //如果等于HTTP_OK(200),说明请求和相应都成功了                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));   //BufferedReader是Reader的子类                        char[] buffer = new char[1024];                        reader.read(buffer);                        String response = new String(buffer);                        Message message = new Message();                        message.what = SHOW_RESPONSE;                        //将服务器返回的结果存放到message中                        message.obj = response;                        handler.sendMessage(message);                    }                } catch (IOException e) {                    e.printStackTrace();                } finally {                    if (connection != null){                        connection.disconnect();                    }                }            }        }).start();    }}
        运行后,在TextView中得到的是服务器返回给我们的HTML代码,我们平时看到的是经过浏览器解析后,展示给我们的漂亮的网页。

        如果我们想要提交数据给服务器,只需要将HTTP请求的方法改成POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&符号隔开:

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

    2.2 使用HttpClient

        1. HttpClient是一个接口,因此无法创建它的实例,通常情况下会创建一个DefaultHttpClient的实例,如下:

HttpClient httpClient = new DefaultHttpClient();
        2. 接下来如果想要发起一条GET请求,可以创建一个HttpGet对象,并传入目标的网络地址,然后调用HTTPClient的extcute()方法:

HttpGet httpGet = new HttpGet("www.baidu.com");HttpResponse httpResponse = httpClient.execute(httpGet);
        如果发起的是POST请求,我们需要创建一个HTTPPost对象,并传入目标的网络地址,通过一个NameValuePair集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity中,然后调用HTTPPost的setEntity()方法将构建好的UrlEncodedFormEntity传入:
List<NameValuePair> params = new ArrayList<NameValuePair>();params.add(new BasicNameValuePair("username","admin"));params.add(new BasicNameValuePair("password","123456"));UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,"utf-8");httpPost.setEntity(entity);HttpResponse httpResponse = httpClient.execute(httpPost);
        3. 执行execute()方法之后会返回一个HttpResponse对象,服务器返回的数据都包含在里面。通常我们会先取出状态码,如果等于200就说明请求和相应都成功了,如下所示:
if(httpResponse.getStatusLine().getStatusCode() == 200) {        //请求和相应成功了}

        4. 接下来在if判断内部取出服务返回的具体内容,可以调用getEntity()方法获取到一个HttpEntity实例,然后再用EntityUtils.toString()这个静态方法将HttpEntity转换成字符串即可,如下所示:

HttpEntity entity = httpResponse.getEntity();String response = EntityUtils.toString(entity,"utf-8");    //这里如果如果服务器返回的数据是有中文的,直接调用EntityUtils.toString(entity)方法进行转换会有乱码的情况出现,所以我们将字符指定成utf-8语言


1 0
原创粉丝点击