android开发网络请求的几种方法

在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行时都会报错,这是因为Android在4.0以后为了防止应用的

ANR(aplication Not Response)异常,就针对此问题有两种解决的方法:

1.可以再Activity的onCreate()方法中加入这样一段代码,如下:

  // 强制直接在UI线程中进行网络操作
  StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwo()
                .penaltyLog().build());

  StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
        .penaltyLog().penaltyDeath().build());

2.一般情况我们应该这样做

启动一条子线程进行你的网络请求。

当然,如果你的应用程序执行的网络请求数据量很小的话,可以使用第一种方案

启动线程访问网络的方式也有多种:

(1)启用异步任务线程类去访问网络(GET方式请求网络)
    
    我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话

    mTask = new MyTask();

    mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类

    private class MyTask extends AsyncTask {  
            //onPreExecute方法用于在执行后台任务前做一些UI操作  
            @Override  
            protected void onPreExecute() {    
            }  
          
            //doInBackground方法内部执行后台任务,不可在此方法内修改UI  
            @Override  
            protected String doInBackground(String... params) {    
                try {  
                    HttpClient client = new DefaultHttpClient();  
                    HttpGet get = new HttpGet(params[0]);  
                    HttpResponse response = client.execute(get);  
                    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
                            HttpEntity entity = response.getEntity();  
                            InputStream is = entity.getContent();  
                            long total = entity.getContentLength();  
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                             byte[] buf = new byte[1024];  
                            int count = 0;  
                            int length = -1;  
                            while ((length = is.read(buf)) != -1) {  
                                baos.write(buf, 0, length);  
                                count += length;  
                                //调用publishProgress公布进度,最后onProgressUpdate方法将被执行  
                                publishProgress((int) ((count / (float) total) * 100));    
                            }  
                            return new String(baos.toByteArray(), "UTF-8");  
                       }  
                } catch (Exception e) {  
                    Log.e(TAG, e.getMessage());  
               }  
                return null;  
            }  
          
            //onProgressUpdate方法用于更新进度信息  
            @Override  
            protected void onProgressUpdate(Integer... progresses) {     
            }  
          
            //onPostExecute方法用于在执行完后台任务后更新UI,显示结果  
            @Override  
            protected void onPostExecute(String result) {  
            //这里返回的result为成功访问网络后获得的数据
                mTask.cancel(true);
            }  
          
            //onCancelled方法用于在取消执行中的任务时更改UI  
            @Override  
            protected void onCancelled() {  
            }  
        }  

(2)启用异步任务线程类去访问网络(POST方式请求网络模拟登录)
    
    我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话

    mTask = new MyTask();

    mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类

    private class MyTask extends AsyncTask {  
            //onPreExecute方法用于在执行后台任务前做一些UI操作  
            @Override  
            protected void onPreExecute() {    
            }  
          
            //doInBackground方法内部执行后台任务,不可在此方法内修改UI  
        @Override  
            protected String doInBackground(String... params) {    
                try {  
                    HttpClient client = new DefaultHttpClient();
            List parameters = new ArrayList();
                    //请求数据(代替了输出流)
                    parameters.add(new BasicNameValuePair("UserName",username));
                    parameters.add(new BasicNameValuePair("Password",psaaword));
                    HttpPost post = new HttpPost(params[0]);
                    post.setEntity(new UrlEncodedFormEntity(parameters,"utf-8"));
                    HttpResponse response = client.execute(post);  
                    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
                            HttpEntity entity = response.getEntity();  
                            InputStream is = entity.getContent();  
                            long total = entity.getContentLength();  
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                            byte[] buf = new byte[1024];  
                            int count = 0;  
                            int length = -1;  
                            while ((length = is.read(buf)) != -1) {  
                                baos.write(buf, 0, length);  
                                count += length;   
                            }  
                            return new String(baos.toByteArray(), "UTF-8");  
                        }  
                } catch (Exception e) {  
                    Log.e(TAG, e.getMessage());  
                }  
                return null;  
            }  
          
            //onProgressUpdate方法用于更新进度信息  
            @Override  
            protected void onProgressUpdate(Integer... progresses) {     
            }  
          
            //onPostExecute方法用于在执行完后台任务后更新UI,显示结果  
            @Override  
            protected void onPostExecute(String result) {
                mTask.cancel(true);
            }  
          
            //onCancelled方法用于在取消执行中的任务时更改UI  
            @Override  
            protected void onCancelled() {  
            }  
        }  

上面的两种方法都是采用HttpClient进行网络的访问请求,我们还可以用HttpURLConnection进行网络的访问请求,样式都比较类似,这里不一一举例。

你可能感兴趣的:(Android)