现在看看彩吧3d图谜第一版版的彩吧3d图谜第一版行代码过不过时?懂的来回答,不懂别来。

722157 条评论分享收藏感谢收起赞同 9843 条评论分享收藏感谢收起Gradle 系列学习(二)-- 学点Groovy来理解build.gradle代码
发布时间:&&
文章分类:
这篇的侧重点不是在介绍 groovy 的基本语法,而是介绍跟 build.gradle 比较相关的一些知识点吧,另外在末尾会附上一些 groovy 学习链接,有兴趣的可以继续去学习。
开始学习 Groovy 前,引用徐宜生的《Android群英传:神兵利器》书中的一句话来介绍 Groovy:
Groovy 对于 Gradle,就好比
对于 Android。了解一些基本的 Groovy 知识,对于掌握 Gradle 是非常有必要的。
Groovy 是什么
Groovy 是一种脚本语言,既然是脚本语言,那么它也就有脚本语言的那些特点:使用动态类型、末尾不用分号等等。另外,它又是基于 Java 上设计的语言,也就是 Groovy 兼容 Java,可以使用 JDK 里的各种方法,你可以在 Groovy 文件里写 Java 代码里,照样可以正常编译运行。
Groovy 语法
关于语法的详细的介绍在末尾有链接,这里就只是挑出我认为比较重要的,而且跟 java 有区别的,在阅读代码时可能会看不懂的一些语法进行记录。
1.注释、标识符方面跟 Java 基本一样。
2.基本数据类型,运算方面
这方面在 build.gradle 文件里也不怎么常见到使用,因为 groovy 是动态类型,定义任何类型都可以只使用 def 来定义,所以如果使用具体的比如 char, int 等类型时需要强制转换吧。有需要的可以自己查阅末尾的参考链接。
3.字符串方面
java 只支持用 "..." 双引号来表示字符串
groovy 支持使用 '...' , "..." , '''...''' , """...""" , /.../ , $/.../$ 即单引号,双引号等6种方法来表示字符串
至于各种表示方法有什么区别,具体可以参考末尾的链接,这里简单提提, '...' , "..." 只支持单行字符串,不支持多行,剩下的四种都支持多行字符串,如下图
斜杠我也很少见,常见的是带有 ${} 的字符串,比如: println "blog's url: ${blogUrl}" 这是 groovy 的 GString 特性,支持字符串插值,有点了类似于变量引用的概念,但注意,在 '...' , '''...''' 单引号表示的字符串里不支持 ${} 。当然,如果你要使用 java 的方式,用 + 来拼接也可以。
4.集合方面(List、Map)
定义和初始化
定义很简单,List 的话使用 [] 定义,各项用 , 隔开即可。Map 的话使用 [:] ,各项也是用 , 隔开,如:
def numList = [1, 2, 3]
def map [1:"dasu", dasu:24] //Map, : 前是key,如1, : 后是value, 如dasu
有一点跟 java 不同的是, groovy 集合里不要求每一项都是同类型,比如可以这样定义 def list = [1, 'dasu', true] ,集合里包含数字,字符串,布尔值三种类型。
通过下标操作符 [] 读写元素值,并使用正索引值访问列表元素或负索引值从列表尾部访问元素,也可以使用范围,或使用左移 && 追加列表元素,如
//========= List 使用 ================
println numList[1]
println numList[-1] //输出 3
numList[2] = 4
// println numList[2]将输出 4
numList[3] = 5
numList && "dasu" //现在numList = [1, 2, 4, 5, "dasu"]
//========== Map 使用 ================
println map[1]
//输出 dasu
println map.dasu
//输出 24, key是字符串的话可以这样访问
map[3] = "I am dasu" // 在map里加入一个[3:"I am dasu"]项
跟 java 不同的是, groovy 并不存在下标访问越界,当下标为负数时则从右开始算起,当指定的下标没有存放值时返回 null。
5.数组方面
groovy 其实没有严格区分数组和集合,数组的定义和使用方法跟集合一样,只是你需要强制声明为数组,否则默认为集合,如
String[] arrStr = ['Ananas', 'Banana', 'Kiwi']
def numArr = [1, 2, 3] as int[] //as 是 groovy 关键字
上面的初始化方式是不是跟 java 不一样,这一点需要注意下,java 是用 {} 来初始化,但在 groovy 里面, {} 表示的是闭包,所以这点需要注意一下。
上面的是 groovy 与 java 不同的一些基本语法,下面介绍一些我自己认为是 groovy 比较重要的特性,如果要看懂 build.gradle 里的代码,明白下面介绍的会比较有帮助。
6.方法的简化使用
方法的括号可以省略
groovy 定义方法时可以不声明返回类型和参数类型,也可以不需要 return 语句,最后一行代码默认就是返回值。
而在调用方法时可以将括号省略,不省略的时候如下
def add(a, b) {
println add(1,2)
上面的方式不陌生吧,再来看看下面的代码
println add 1, 2 //输出 3, add方法同上
上面就是调用方法时省略掉圆括号的写法,再来看一种情况
def getValue(Map map) {
map.each {
println it.key + ":" + it.value
def map = [author:"dasu"]
getValue(map) //输出 author:dasu
这次定义一个参数为 map 类型的方法,如果我们在调用方法的时候才对参数进行定义和初始化会是什么样的呢?如下
getValue(author: "dasu") //输出 author:dasu
之前说过了,groovy 调用方法时可以将括号省略掉,这样一来再看下
getValue author: "dasu" //输出 author:dasu
这样子的格式是不是看着觉得很眼熟,没错,就是 build.gradle 里的第一行代码。
如果有看过我的上一篇
博客的话,现在对疑问1是不是就有些理解了呢。
上图那代码如果把省略的括号补上的话,大家应该就会熟悉点了
// apply plugin: 'com.android.application'
def map = [plugin: 'com.android.application']
apply(map)
调用了 apply() 方法,该方法传入一个 map 参数,我们来看看是不是这样,用as查看下源码,如下
没错吧,apply() 其实是个方法,参数为 map 类型,而且 key 的取值也给你规定了 from , plugin , to 三种,是不是确实在别人的 build.gradle 代码里也有看见过类似 apply from *** ,这样一来就明白多了吧。
好了,然后你再重新去看一下 build.gradle 里的代码,是不是对每一行的代码都有了新的看法了。
其实 build.gradle 里的每一行代码都是在调用一个方法,比如下面这些我们常见的:
每一行都是在调用一个方法,前面是方法名,后面是方法的参数,只是把括号省略掉了而已,感兴趣的你可以再自己用as点进去看看源码是不是这样。
方法最后一个参数是闭包可以提取出来接到后面
闭包是 groovy 的一大特性,我理解也不深,也讲不大清楚,感兴趣的可自行网上查阅学习,简单的说就是一个用 {..} 包起来的代码块,比如 build.gradle 里的 defaultConfig{...} , buildTypes{...} , dependencies{...} 等等这些大括号包起来的代码块就是闭包,闭包代码块最后一句代码作为闭包的返回值。
当闭包作为方法的最后一个参数,可以将闭包从参数圆括号中提取出来接在最后,如果闭包是唯一的一个参数,则方法参数所在的圆括号也可以省略。对于有多个闭包参数的,只要是在参数声明最后的,均可以按上述方式省略,举个例子。
//定义 add 方法
def add(a, Closure c) {
println a + c.call()
//调用方法
add(1, {1+1}) //输出 3
上面定义一个 add 方法,最后一个参数为闭包,调用的时候传入一个闭包,闭包的最后一行代码 1+1 作为闭包返回值返回,闭包返回值作为方法的第二个参数传入方法中计算加法,所以最终输出3。上面的调用也可以写成下面的方式:
} //输出 4
注意,这是调用 add() 方法,而不是在定义,1 是第一个参数,括号后的闭包 { 1+2 } 是方法的第二个参数,这就是 groovy 的特性,闭包可以提取出来。那么再想想,如果方法只有一个闭包参数,再结合 groovy 可以省略掉括号的特性,这样子调用一个方法将会是什么样子呢?
//定义 method 方法
def method(Closure c) {
println c.call()
//调用方法
} //输出 I'm dasu
是不是又感觉很熟悉,对吧,就是 build.gradle 里的 defaultConfig{...} , buildTypes{...} , dependencies{...} 等等这些。
所以,结合上面讲的两点:可以省略方法括号和闭包可以提取接到括号后面,这样一来, build.gradle 里的代码其实就是在调用各种方法, defaultConfig 是一个方法, compileSdkVersion 也是一个方法。 build.gradle 里的每一行代码前面是方法名,后面则是方法需要的参数,参数有的是基本类型,有的则是闭包类型。
集合遍历 each/all
就先把上一篇博客里的在一段在 build.gradle 里很常见的代码贴出来
这段代码作用就是对打包生成的 apk 按照规定的格式进行重命名,在很多大神的 build.gradle 里都会遇见过,其实这一段代码就是 groovy 代码, all 和 each 是集合的一种操作, all 后面跟着的是一个参数为 variant 的闭包,表示对 applicationVariants 集合里所有的对象都运行后面的闭包,同理 each 后面也是跟着一个参数为 output 的闭包,类似于 java 里的 for 循环操作。所以这里要理解的应该是 applicationVariants 代表的是什么,这点我也还不是很懂,后面如果搞懂了的话会在之后的博客里介绍出来。
另外,我还有个疑问来着, all 操作和 each 操作有什么区别么,感觉都是对集合里所有的元素进行操作,如果有懂的能够告知就太感谢了,查了挺多资料貌似还不是很明白。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持
可能感兴趣的文章:
本文永久链接:
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
[美] 詹姆斯·格雷克 / 高博 / 人民邮电出版社 / 2013-10 / 69.00元
人类与信息遭遇的历史由来已久。詹姆斯o格雷克笔下的这段历史出人意料地从非洲的鼓语讲起(第1章)。非洲土著部落在尚未直接跨越到移动电话之前,曾用鼓声来传递讯息...
在线压缩/解压 CSS 代码
URL 编码/解码
UNIX 时间戳转换
12345678910
12345678910
12345678910
123456789101、WebView的用法
下面是一个很简单的例子,就是显示百度首页。
布局文件:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"&
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" /&
package com.test.
import android.app.A
import android.os.B
import android.webkit.WebV
import android.webkit.WebViewC
import com.test.R;
* Created by Administrator on
public class WebActivity extends Activity {
private WebView webV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
webView.loadUrl("http://www.baidu.com");
最后别忘了添加访问网络的权限:
android:name="android.permission.INTERNET" /&
2、使用HTTP协议访问网络
对于HTTP协议,你只需要稍微了解一些就足够了,它的工作原理特别的简单,就是客户端向服务器发出一条HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。是不是非常简单?一个浏览器的基本工作原理也就是如此了。在Android上发送HTTP请求的方式一般有两种,HttpURLConnection和HttpClient。
使用HttpURLConnection
下面看一个例子,
布局文件:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"&
android:id="@+id/send_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send request" /&
android:layout_width="match_parent"
android:layout_height="match_parent"&
android:id="@+id/response"
android:layout_width="match_parent"
android:layout_height="wrap_content" /&
package com.test.
import android.app.A
import android.os.B
import android.os.H
import android.os.M
import android.view.V
import android.widget.B
import android.widget.TextV
import com.test.R;
import java.io.BufferedR
import java.io.InputS
import java.io.InputStreamR
import java.net.HttpURLC
import java.net.URL;
* Created by Administrator on
public class HttpURLConnectionActivity extends Activity implements View.OnClickListener {
private static final int SHOW_RESPONSE = 0;
private Button btnS
private TextView txtR
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_urlconnection);
btnSend = (Button) findViewById(R.id.send_request);
txtResponse = (TextView) findViewById(R.id.response);
btnSend.setOnClickListener(this);
public void onClick(View v) {
if (v.getId() == R.id.send_request) {
SendRequestWithHttpURLConnection();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.
txtResponse.setText(response);
private void SendRequestWithHttpURLConnection() {
new Thread(new Runnable() {
public void run() {
HttpURLConnection conn = null;
URL url = new URL("http://www.baidu.com");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(8000);
conn.setReadTimeout(8000);
InputStream in = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
Message msg = new Message();
msg.what = SHOW_RESPONSE;
msg.obj = response.toString();
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}).start();
声明权限:
android:name="android.permission.INTERNET" /&
上面是GET方式(即从服务器那里获取数据),那么如果是想要提交数据给服务器应该怎么办呢?其实也不复杂,只需要将HTTP请求的方法改成POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&符号隔开,比如说我们想要向服务器提交用户名和密码,就可以这样写:
connection.setRequestMethod(" POST")
DataOutputStream out = new DataOutputStream(connection.getOutputStream())
out.writeBytes("username=admin&password=123456")
使用HttpClient
HttpClient是Apache提供的HTTP网络访问接口,从一开始的时候就被引入到了Android API中。它可以完成和HttpURLConnection几乎一模一样的效果,但两者之间的用法却有较大的差别,下面通过一个例子来说明:
布局文件:
和上个例子一模一样。
声明权限:
和上个例子一模一样。
上面是GET方式(即从服务器那里获取数据),那么如果是发起一条POST请求会比GET稍微复杂一点,我们需要创建一个HttpPost对象,并传入目标的网络地址,如下所示:
HttpPost http Post = new Http Post ("http://www.baidu.com");
然后通过一个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);
接下来的操作就和HttpGet一样了。
3、解析XML格式数据
通常情况下,每个需要访问网络的应用程序都会有一个自己的服务器,我们可以向服务器提交数据,也可以从服务器上获取数据。不过这个时候就出现了一个问题,这些数据到底要以什么样的格式在网络上传输呢?随便传递一段文本肯定是不行的,因为另一方根本就不会知道这段文本的用途是什么。因此,一般我们都会在网络上传输一些格式化后的数据,这种数据会有一定的结构规格和语义,当另一方收到数据消息之后就可以按照相同的结构规格进行解析,从而取出他想要的那部分内容。
在网络上传输数据时最常用的格式有两种,XML和JSON。
(1)Pull解析方式
在上面一节的例子上加代码,详见代码注释:
public class MainActivity extends Activity implements OnClickListener {
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
public void run() {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://10.0.2.2/get_data.xml");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
parseXMLWithPull(response);
} catch (Exception e) {
e.printStackTrace();
}).start();
private void parseXMLWithPull(String xmlData) {
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();
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);
eventType = xmlPullParser.next();
} catch (Exception e) {
e.printStackTrace();
(2)SAX解析方式
SAX解析也是一种特别常用的XML解析方式,虽然它的用法比Pull解析要复杂一些,但在语义方面会更加的清楚。
通常情况下我们都会新建一个类继承自DefaultHandler,并重写父类的五个方法,如下所示:
public class ContentHandler extends DefaultHandler {
private String nodeN
private StringB
private StringB
private StringB
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
nodeName = localN
public void characters(char[] ch, int start, int length) throws SAXException {
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);
public void endElement(String uri, String localName, String qName) throws SAXException {
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());
id.setLength(0);
name.setLength(0);
version.setLength(0);
public void endDocument() throws SAXException {
接下来的工作就非常简单了,修改MainActivity中的代码,如下所示:
public class MainActivity extends Activity implements OnClickListener {
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
public void run() {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://10.0.2.2:8080/ get_data.xml");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
parseXMLWithSAX(response);
} catch (Exception e) {
e.printStackTrace();
}).start();
private void parseXMLWithSAX(String xmlData) {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
ContentHandler handler = new ContentHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
4、解析JSON格式数据
比起XML,JSON的主要优势在于它的体积更小,在网络上传输的时候可以更省流量。但缺点在于,它的语义性较差,看起来不如XML直观。
(1)使用JSONObject(谷歌官方提供)
解析方法:
private void parseJSONWithJSONObject(String jsonData) {
JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i & jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
} catch (Exception e) {
e.printStackTrace();
(2)使用GSON(谷歌的开源库)
GSON并没有被添加到Android官方的API中,因此如果想要使用这个功能的话,则必须要在项目中添加一个GSON的Jar包。首先我们需要将GSON的资源压缩包下载下来,下载地址是:http://code.google.com/p/google-gson/downloads/list。
GSON库究竟是神奇主要就是可以将一段JSON格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析了。
比如说一段JSON格式的数据如下所示:
{"name":"Tom","age":20}
那我们就可以定义一个Person类,并加入name和age这两个字段,然后只需简单地调用如下代码就可以将JSON数据自动解析成一个Person对象了:
Gson gson = new Gson();
Person person = gson.fromJson(jsonData, Person.class);
如果需要解析的是一段JSON数组会稍微麻烦一点,我们需要借助TypeToken将期望解析成的数据类型传入到fromJson()方法中,如下所示:
List&Person& people = gson.fromJson(jsonData, new TypeToken&List&Person&&() {}.getType());
5、网络编程的最佳实践(利用Java的回调机制来将服务器响应的数据进行返回)
通常情况下我们都应该将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法,当想要发起网络请求的时候只需简单地调用一下这个方法即可。
比如使用如下的写法:
public class HttpUtil {
public static String sendHttpRequest(String address) {
HttpURLConnection connection = null;
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();
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();
以后每当需要发起一条HTTP请求的时候就可以这样写:
String address = "http://www.baidu.com";
String response = HttpUtil.sendHttpRequest(address);
在获取到服务器响应的数据后我们就可以对它进行解析和处理了。但是需要注意,网络请求通常都是属于耗时操作,而sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用sendHttpRequest()方法的时候使得主线程被阻塞住。
你可能会说,很简单嘛,在sendHttpRequest()方法内部开启一个线程不就解决这个问题了吗?其实不是像你想象中的那么容易,因为如果我们在sendHttpRequest()方法中开启了一个线程来发起HTTP请求,那么服务器响应的数据是无法进行返回的,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器还来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。
那么遇到这种情况应该怎么办呢?其实解决方法并不难,只需要使用Java的回调机制就可以了,下面就让我们来学习一下回调机制到底是如何使用的。
首先需要定义一个接口,比如将它命名成HttpCallbackListener,代码如下所示:
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
可以看到,我们在接口中定义了两个方法,onFinish()方法表示当服务器成功响应我们请求的时候调用,onError()表示当进行网络操作出现错误的时候调用。这两个方法都带有参数,onFinish()方法中的参数代表着服务器返回的数据,而onError()方法中的参数记录着错误的详细信息。
接着修改HttpUtil中的代码,如下所示:
public class HttpUtil {
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
new Thread(new Runnable() {
public void run() {
HttpURLConnection connection = null;
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();
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()方法中。
现在sendHttpRequest()方法接收两个参数了,因此我们在调用它的时候还需要将HttpCallbackListener的实例传入,如下所示:
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
public void onFinish(String response) {
public void onError(Exception e) {
这样的话,当服务器成功响应的时候我们就可以在onFinish()方法里对响应数据进行处理了,类似地,如果出现了异常,就可以在onError()方法里对异常情况进行处理。如此一来,我们就巧妙地利用回调机制将响应数据成功返回给调用方了。
另外需要注意的是,onFinish()方法和onError()方法最终还是在子线程中运行的,因此我们不可以在这里执行任何的UI操作,如果需要根据返回的结果来更新UI,则仍然要使用上一章中我们学习的异步消息处理机制。
Android学习笔记——网络技术
在手机端使用HTTP协议和服务器端进行网络交互,并对服务器端返回的数据进行解析。这是Android最常使用的网络技术。
1、WebView
借助WebView控件,可在应用程序中嵌入一个浏览器。 ...
HTTP基础与Android之——使用HttpClient和HttpURLConnection
1客户端连接服务器实现内部的原理
GET方式和POST方式的差别
HTTP返回请求数据的三种方式
2使用HTTP协议访问网络
3HttpCient
简单来说用HttpClient发送请求接收响应都很简...
1、功能需求及技术可行性分析
(1)、先对程序进行需求分析
可以罗列出全国所有的省、市、县。
可以查看全国任意城市的天气信息。
可以自由地切换城市,去查看其他城市...
1、传感器简介手机中内置的传感器是一种微型的物理设备,它能够探测、感受到外界的信号,并按一定规律转换成我们所需要的信息。Android手机通常都会支持多种类型的传感器,如光照传感右器、加速度传感器、地...
本篇笔记介绍了Toolbar、DrawerLayout、Toolbar导航按钮、NavigationView、FloatingActionButton、Snackbar、CoordinatorLayo...
https://github.com/breakfrox/Coolweather.git
就是标题说的那样/囧,将酷欧天气用kotlin编写了,感兴趣的同学可以参考一下
也不知道说啥, 原本以...
第一行代码(第二版)第一章主要介绍了Android系统架构、重要版本、应用开发特色以及详细讲解了如何创建第一个Android项目和如何创建模拟器,还详细讲解了AndroidStudio项目下比较重要的...
没有更多推荐了,

我要回帖

更多关于 福彩3d图谜第一版 的文章

 

随机推荐