关于Android客户端和服务器之间的通信,对于我这种新手菜鸟来说,是很头疼的事。
下了很多实例、教程,但是感觉方法各不相同,而且都比较繁琐,又牵扯到线程、异步任务、更新UI这些头大的东西。
终于,在慕课网上无意间看到一个Volley框架,是谷歌官方的一个通信框架,大大简化了GET/POST请求,据说对请求图片资源也有优势。
废话不多说,做了个小DEMO,使用volley框架的get方式以及两种post方式进行数据请求。
输入手机号查询归属地,在聚合网申请了个API的key用于测试。
项目源码和Volley的jar包已打包。点此下载源码
先看效果演示:
首先新建类MyApplication.java 用于管理请求队列
package com.fukang.phonenumberlocation;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import android.app.Application;
public class MyApplication extends Application { // 继承自Application类
public static RequestQueue queues;
@Override
public void onCreate() {
super.onCreate();
queues = Volley.newRequestQueue(getApplicationContext());// 实例化请求队列对象
}
public static RequestQueue getQueues() {
return queues;
}
}
//此处设置联网权限
package com.fukang.phonenumberlocation;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import com.android.volley.AuthFailureError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import android.app.Activity;
import android.os.Bundle;
import android.text.Layout;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
* 基于Volley框架的get/post方式查询电话归属地
*
* @author fk 2015.08.11
*/
public class MainActivity extends Activity {
// 定义变量
EditText et_number;
TextView tv_province, tv_city, tv_company, tv_number;
Button btn_get, btn_post_string, btn_post_jo;
Listener listener; // 成功得到返回数据监听器
Response.ErrorListener errorListener; // 失败得到返回数据监听器
String number = null; // 定义输入的电话号码为全局变量
LinearLayout layout_result; // 显示结果的布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);// 加载布局资源
initView();// 初始化绑定控件
setResponseListener();// 设置响应监听器
setOnClickListener();// 设置按钮点击监听器
}
/*
* 设置响应监听器
*/
private void setResponseListener() {
// 获取数据成功监听器
listener = new Listener() {
// 聚合网返回JSON格式示例:
// {
// "resultcode":"200",
// "reason":"Return Successd!",
// "result":{
// "province":"浙江",
// "city":"杭州",
// "company":"中国移动",
// }
// }
@Override
public void onResponse(String arg0) {
System.out.println(arg0);
try {
JSONObject jo = new JSONObject(arg0);// 首先取得外层JSONObject,即{"resultcode","reason","result"}
JSONObject result = jo.getJSONObject("result");// 再取得需要的"result"这个JSONObject
String province = result.getString("province");// 依次从中取出省份、城市及运营商
String city = result.getString("city");
String company = result.getString("company");
tv_number.setText(number);// 更新UI显示
tv_province.setText(province);
tv_city.setText(city);
tv_company.setText(company);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
// 获取数据失败监听器
errorListener = new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
tv_province.setText("请求错误!");
}
};
}
private void setOnClickListener() {
btn_get.setOnClickListener(new OnClickListener() {
// 设置查询按钮监听器
@Override
public void onClick(View v) {
number = et_number.getText().toString();// 取得输入的电话号码
layout_result.setVisibility(View.VISIBLE);// 显示结果布局
volley_Get(number);// 调用Get方法,传入该电话号码
et_number.setText("");// 清空输入框
}
});
btn_post_string.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
number = et_number.getText().toString();// 取得输入的电话号码
layout_result.setVisibility(View.VISIBLE);// 显示结果布局
volley_Post_String(number);// 调用第一种Post方法,传入该电话号码
et_number.setText("");// 清空输入框
}
});
btn_post_jo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
number = et_number.getText().toString();// 取得输入的电话号码
layout_result.setVisibility(View.VISIBLE);// 显示结果布局
volley_Post_JO(number);// 调用第二种Post方法,传入该电话号码
et_number.setText("");// 清空输入框
}
});
}
private void initView() { //绑定控件资源
et_number = (EditText) findViewById(R.id.ed_number);
tv_number = (TextView) findViewById(R.id.tv_number);
tv_province = (TextView) findViewById(R.id.tv_province);
tv_city = (TextView) findViewById(R.id.tv_city);
tv_company = (TextView) findViewById(R.id.tv_company);
btn_get = (Button) findViewById(R.id.btn_get);
btn_post_string = (Button) findViewById(R.id.btn_post_string);
btn_post_jo = (Button) findViewById(R.id.btn_post_jo);
layout_result = (LinearLayout) findViewById(R.id.layout_result);//显示结果的布局
}
private void volley_Get(String number) { //方法一:使用get方式请求数据
String url = "http://apis.juhe.cn/mobile/get?phone=" + number
+ "&key=ff73250e4692b885041b9ac2240ac6e8";// 得到完整GET请求url字符串
StringRequest request = new StringRequest(Method.GET, url, listener,
errorListener);// 四个参数:GET方法;url地址;成功监听器;失败监听器;
request.setTag("myGet");// 设置请求标签
MyApplication.getQueues().add(request);// 得到请求队列,并把当前请求加入队列中
}
private void volley_Post_String(String number) { //方法二:使用post方式、StringRequest请求数据
final String url = "http://apis.juhe.cn/mobile/get?";
final String phone = number;
final String key = "ff73250e4692b885041b9ac2240ac6e8";
StringRequest request = new StringRequest(Method.POST, url, listener,
errorListener) {
@Override
protected Map getParams() throws AuthFailureError { //得到map中的参数
Map map = new HashMap();
map.put("phone", phone);
map.put("key", key);
return map;
}
};
request.setTag("myPost");
MyApplication.getQueues().add(request);
}
private void volley_Post_JO(String number) {
final String url = "http://apis.juhe.cn/mobile/get?";
final String phone = number;
final String key = "ff73250e4692b885041b9ac2240ac6e8";
HashMap map = new HashMap();
map.put("phone", phone);
map.put("key", key);
JSONObject jsonRequest = new JSONObject(map);
JsonObjectRequest jo_request = new JsonObjectRequest(
Request.Method.POST, url, jsonRequest,
new Listener() {
@Override
public void onResponse(JSONObject arg0) {
System.out.println(arg0.toString());
Toast.makeText(MainActivity.this, arg0.toString(),
Toast.LENGTH_LONG).show();
try {
JSONObject result = arg0.getJSONObject("result");// 取得需要的"result"这个JSONObject
String province = result.getString("province");// 依次从中取出省份、城市及运营商
String city = result.getString("city");
String company = result.getString("company");
tv_number.setText(phone);// 更新UI显示
tv_province.setText(province);
tv_city.setText(city);
tv_company.setText(company);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, errorListener);
jo_request.setTag("jo_Post");
System.out.println(jo_request.toString());
MyApplication.getQueues().add(jo_request);
}
}
Volley框架还有对图片的高效加载与缓存,暂不研究了。
PS:如有高手,能否告诉我为何最后一种post_jo请求方式返回结果为“错误的请求key”...
通过system.out比较,和第一种post最终请求内容都一样,key也是复制粘贴绝对没错,十分不解!