【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

时间:2022-08-30 16:11:03

目录(?)[-]

  1. HTTP GET小例子
    1. 简单小例子
    2. 出现异常NetworkOnMainThreadException
    3. 通过StrictMode进行处理
    4. URL带键值对

Andriod应用可利用service提供很多功能,例如利用Google Maps API,现在我们将聚焦在HTTP serice中。

Android SDK提供HttpClient,和J2EE中的接口非常相似。最常用的就是HTTP GET和HTTP POST。相关内容也可以阅读Android学习笔记(四五):互联网通信-HttpClient、XML解析(W3C)

HTTP GET小例子

因为要访问互联网,所以要在AndriodManifest.xml文件中加入android.permission.INTENT的权限。

简单小例子

小例子很简单,发送一个HTTP Get,请求打开某个网址,并将收到的HTTP响应通过Log打印出来。

public class HttpGetDemo extends Activity{  
    @Override 
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main);  
                 
        BufferedReader in = null; 
        try{  
            //【Step 1】创建一个HttpClient的对象(或使用已有的)
            HttpClient client = new DefaultHttpClient(); 
            //【Step 2】实例化一个HTTP GET或者HTTP POST,本例是HTTP GET 
            HttpGet request = new HttpGet("
http://www.baidu.com"); 
            //【Step 3】设置HTTP参数,本例子是最简单地打开某个网址的HTTP GET,无需设置 
           //【Step 4】通过HttpClient来执行HTTP call(发出HTTP请求)  
            HttpResponse response = client.execute(request);
 
            //【Step 5】处理HTTP响应,本例将整个响应的内容(HTTP 200消息的body)都在String中。 
            in = new BufferedReader( 
                    new InputStreamReader( 
                            response.getEntity().getContent())
); 
            StringBuffer buff = new StringBuffer(""); 
            String line = ""; 
            String NL = System.getProperty("line.separator");  //实际上就是“\n”,可自动适配系统的换行符。 
            while((line = in.readLine()) != null ){ 
                buff.append(line + NL); 
            } 
            in.close();  
            Log.d("PRO",buff.toString());  
        }catch(Exception e){ 
            e.printStackTrace(); 
            Log.d("PRO",e.toString()); 
        }finally{  //try{}catch(){}finally{}中finally见得稍微少,但是很有用,无论是否有异常,都会执行finally的代码,常用于xx.close()。
            if(in != null){ 
                try{ 
                    in.close(); //关闭BufferedReader,同时也关闭了底层的HTTP connection
                }catch(Exception e){ 
                    e.printStackTrace();  
                    Log.d("PRO","error in finally:\n" + e.toString()); 
                } 
            } 
        }         
    }  
    
}

出现异常NetworkOnMainThreadException

这是很简单的例子,但是运行的时候却报错:

【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

例子很简单,代码没有什么为题,何故?根据文档,这个错误会在应用尝试在主线程(Main)中进行网络操作而产生,只在Honeycomb SDK或更高版本出现。也就是说在Android 3.0及以上版本,如果在主线程进行网络访问,会扔出NetworkOnMainThreadException。而检查AndroidManifest.xml文件,发现:

<uses-sdk  android:minSdkVersion="14" …… />

即运行在Android 4.0及以上的版本。Android 3.0对应为API level 10,我们只需简单地改为:

<uses-sdk  android:minSdkVersion="9" />

Android这样的处理是有道理的,我们注意到代码当中有一行:

/* 建立HTTP的TCP连接(包括之前对网址的DNS解析),发送HTTP GET请求,等待HTTP response消息。这一语句执行了太多内容,有些步骤,可能会因为网络问题,出现长时间的等待才能连接到(或最终不能连接)网站。因此这语句的执行时间可能会很长,建议放在线程中进行后台处理,而不是主线程(同时也是UI线程)中,否则会造成activity因执行该语句造成的UI无响应问题。另外如果网页很大,需要读取很久,在main thread会由于执行该语句导致UI暂时无响应(我不太确定读取网页是在execute,还是在后面in中作为流的方式读取读取,但是我倾向于在execute中读完,因为已经获得HttpResponse对象)*/
HttpResponse response = client.execute(request);

通过StrictMode进行处理

对NetworkOnMainThreadException的合理处理就是将网络访问放置在线程中,本例为了演示直接放置在activity中,在正常情况下,不应如此处理。

处理修改API Level之外,要避免异常,同时也需要指定最小运行版本在Android 3.0以上,例如本例最初指定android:minSdkVersion="14"。还可以对代码进行以下处理:

…… 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 
    ……         
    BufferedReader in = null; 
    try{ … }catch(Exception e){ … }finally{…}

StrictMode我们在Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode中介绍过,不禁止运行线程的某些策略,上面的代码不做任何策略检查,当然也可以只放开网络,即也可以用permitNetwork()。

相关的参考BUG处理可参见:http://www.lucazanini.eu/2012/android/the-android-os-networkonmainthreadexception-exception/?lang=en

当然,我们应该明白尽量不要在activity中(main thread)有网络访问代码。

URL带键值对

对于CGI,URL是带有键值对的,最常见的就是搜索网站,网站根据URL携带的信息来确定用户所要搜索的内容。例如:

HttpClient client = new DefaultHttpClient(); 
HttpGet request = new HttpGet("http://www.google.com.hk/#newwindow=1&q=android&safe=strict");
HttpResponse response = client.execute(request);

更多的可以使用HTTP POST方式,我们将继续学习。

本博文涉及的例子代码,可以在Pro Android学习:Http service小例子中下载。

相关链接: 我的Android开发相关文章

【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET的更多相关文章

  1. 【转】 Pro Android学习笔记(七六):服务(1):local和remote

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...

  2. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  3. 【转】 Pro Android学习笔记(七九):服务(4):远程服务的实现

    目录(?)[-] 远程服务的实现小例子 对外开放远程服务的接口 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flow ...

  4. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  5. 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

    目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...

  6. 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP&sol;JSON&sol;XML、异常

    目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...

  7. 【转】 Pro Android学习笔记(七二):HTTP服务(6):HttpURLConnection

    目录(?)[-] Http Get的使用方式 基础小例子 Cookie的使用 重定向 HTTP POST的小例子 基础小例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载 ...

  8. 【转】Pro Android学习笔记(七):了解Content Provider(下上)

    我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...

  9. 【转】 Pro Android学习笔记(七三):HTTP服务(7):AndroidHttpClient

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 不知道此文是否是这个系列中最短的一篇.我们 ...

随机推荐

  1. 【Linux程序设计】之进程控制&amp&semi;守护进程

    这个系列的博客贴的都是我大二的时候学习Linux系统高级编程时的一些实验程序,都挺简单的. 实验题目:Linux环境下的进程控制 实验目的:熟悉并掌握Linux环境下进程的相关函数的应用:守护进程的概 ...

  2. SQL 注入

    我们的团队项目中有课程名称输入框,其中的内容会拼接到类sql查询语句中. 所以可能会产生类sql注入的问题,我们团队采用了利用正则表达式判断输入内容的形式来规避这类注入. 下面简单介绍一下sql注入 ...

  3. 入門必學NO&period;1 Android 初學特訓班&lpar;第四版&rpar; 目錄

    第 01 章 敲開 Android 的開發大門工欲善其事,必先利其器,要學習 Android 應用程式,先取得功能強大的開發工具,就可讓學習事半功倍. 1.1 Android 是啥米?1.2 建構 A ...

  4. golang学习之指针、内存分配

    func pointer_test() { //空指针,输出为nil var p *int fmt.Printf("p: %v\n", p) //指向局部变量,变量值初始为0 va ...

  5. sqlserver2008数据库自动备份的sql脚本及使用bat命令执行脚本

    -----sql脚本 declare @fileName varchar(255) ,--定义备份文件名变量         @dbname varchar(255)--定义备份数据库名变量decla ...

  6. 二进制 转换成十进制 BCD码&lpar;加3移位法)

    "原来的二进制数十几位,则左移时就要左移几位" "二进制数调整BCD码的方法是将二进制码左移8次,每次移位后都检查低四位LSD+3是否大于7,如是则加3,否则不加,高4位 ...

  7. 如何设置datatable的宽度

    本文为博主原创,未经允许不得转载: datatable插件具有很好的自动适应性,在大多数情况下可以自适应,完美的展示列表内容. 实现其自适应的其特性为:"bAutoWidth": ...

  8. 从Vue文件到Html文件

    如下图,通过webpack打包工具,将一个Vue文件生成html,css,js文件.其中js对应的是new Vue({})

  9. &lbrack;leetcode&rsqb;131&period; Palindrome Partitioning字符串分割成回文子串

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  10. strongswan

    StrongSwan is an open source IPsec-based VPN Solution. It supports both the IKEv1 and IKEv2 key exch ...