Volly框架的使用基础版及使用中的一些坑 Ace 网络篇(三)
直接把注释粘过来:
* Volley使用讲解:
* 要实现网络数据请求主要要记住下面三步骤:
* 1.创建RequestQueue对象
* 2.创建XXRequest对象(XX代表String,JSON,Image等等)
* 3.把XXRequest对象添加到RequestQueue中即可
* 该通过Volley的静态方法newRequestQueue(Context)来获取一个请求队列对象
* 内部设计有请求缓存,系统版本区分请求
* 并且设计适合于高并发
*
第一步 新建一个application ,并创建
RequestQueue
/*
*Acein20160202
*/
public class MyApplication extends Application {
private static RequestQueue mQueue;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mQueue = Volley.newRequestQueue(getApplicationContext());
}
public static RequestQueue getRequstQueue() {
return mQueue;
} }
然后在 /VollyDemo/AndroidManifest.xml <application> 标签中添加 : 添加红色部分 再添加一个网络请求权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vollydemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="com.example.vollydemo.MyApplication">
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>
创建StringRequest对象来发起HTTP请求,然后接收相应数据:
*
* 创建StringRequest对象传入四个参数:
* 请求方法GET/POST/或者其他
* 请求服务器的目标地址
* 服务器数据成功响应回调
* 服务器数据失败响应回调
public class MainActivity extends Activity {
private MyApplication mApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vollyGet();
mApplication = new MyApplication();
}
public void vollyGet() {
String url = "http://apis.juhe.cn/mobile/get?phone=15836300559&key=XXXXXXXXXXX你申请的keyXXXXXXXXXXXX";
StringRequest stringRequest = new StringRequest(Method.GET, url, new Listener<String>() {
//请求成功调用
@Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0, Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
//请求失败调用
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
});
stringRequest.setTag("getString");
mApplication.getRequstQueue().add(stringRequest);
}
}
这是最简单的String get 因为是给新手看的 所以 这样写很不优雅 但是给新手看很好,
下面来看JSONget
public void vollyGet() {
String url = "http://apis.juhe.cn/mobile/get?phone=15836300559&key=XXXXXXX你申请的keyXXXXXXXXXXXXX";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.GET, url, null, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
});
jsonObjectRequest.setTag("jsonget");
mApplication.getRequstQueue().add(jsonObjectRequest);
}
来看下StringRequst POST:跟GET唯一不同是 重写了 getParams方法 ,这样post的时候就会自动调用
StringRequest stringRequest = new StringRequest(Method.POST, url, new Listener<String>() {
@Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("phone", "15836300559");
map.put("key", "f64ff5c4c517da17761f112d6c3c0da0");
return map;
}
};
stringRequest.setTag("ace");
mApplication.getRequstQueue().add(stringRequest);
}
来看JSonRequest的POST 非常有趣 JSonRequest 的Method.POST有很多的坑, 还有 网上那些写错的我就纳闷了 你是怎么得到返回数据的 ,或者说你真的实验了吗
来! 看第一个坑: 跟StringRequst 一样 我重写了getparams方法.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, url,null, new Listener<String>() {
@Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("phone", "15836300559");
map.put("key", "f64ff5c4c517da17761f112d6c3c0da0");
return map;
}
};
stringRequest.setTag("ace");
mApplication.getRequstQueue().add(stringRequest);
}
JsonObjectRequest构造中的参数传null,和StringRequest一样去重写getParams()方法来传参。貌似是没问题的?
使用这段代码拿不到服务器返回的数据,反馈的结果是没有传参给服务器。那就看看参数最终是在哪里提交给服务器的。
Debug HurlStack.java中的addBodyIfExists()这个方法,发现request.getBody()==null,也就是没有接收到参数。
StringRequest可以重写getParams来传参是因为Request中的这个方法:
public byte[] getBody() throws AuthFailureError {
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}
重写的getParams的结果会传到这里。
JsonObjectRequest不能重写getParams来传参是因为JsonRequest中的这个方法:
JsonRequest.java
@Override
public byte[] getBody() {
try {
return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
mRequestBody, PROTOCOL_CHARSET);
return null;
}
}
重写了Request.getBody(),这段代码说明 mRequestBody这个变量就是它的参数。这个变量就存在与JsonRequest的构造函数中。
说明,JsonObjectRequest的传参必须通过构造来传,重写getParams()是无法传递的。
下面按正常思路,来踩第二个坑。给JsonObjectRequest的构造传递参数。又会出现什么问题?
private void vollyPost() {
String url = "http://apis.juhe.cn/mobile/get?";
Map<String,String> map = new HashMap<String, String>();
map.put("phone", "15836300559");
map.put("key", "f64ff5c4c517da17761f112d6c3c0da0");
JSONObject jObject = new JSONObject(map);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, url, jObject ,new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, arg0.toString(), Toast.LENGTH_LONG).show();
}
});
jsonObjectRequest.setTag("json_post");
mApplication.getRequstQueue().add(jsonObjectRequest);
}
JsonOnjectRequest Post 可能会出错的方式 :
* 这里的思路是调用JsonObjectRequest带参构造,传参进入不就得了?
* 但是这里还是请求不到数据。
* 原因是使用JsonObjectRequest 如果服务器接受的参数类型是 http://....?key1=value1&key2=value2,
* 而不是json串{key1 : value1,key2 : value2...},参数就会传不进去。
* 可以在 HurlStack.java 的addBodyIfExists方法中看到你传入的参数信息。
一个大写的坑爹,那些教程拜托请不要误导人好吗?特别像我这种菜鸟,很耗费时间的!
怎么办呢?
我找到这个方法 现在在写
http://blog.csdn.net/onlysnail/article/details/47905375
http://www.open-open.com/lib/view/open1434090628333.html
上面的方法还在解决中,我的借口不支持JSON格式的提交所以要重新自定义JsonRequst
接下来是ImageRequest:
- 第三第四个参数分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩,
- 指定成0的话就表示不管图片有多大,都不会进行压缩。
- @param url
- 图片地址
- @param listener
- @param maxWidth
- 指定允许图片最大的宽度
- @param maxHeight
- 指定允许图片最大的高度
- @param decodeConfig
- 指定图片的颜色属性,Bitmap.Config下的几个常量.
- @param errorListener
public class MainActivity extends Activity {
private MyApplication mApplication;
private ImageView iv_image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url ="http://pic.cnblogs.com/avatar/859887/20160120170921.png";
mApplication = new MyApplication();
initView();
ImageRequest mRequest = new ImageRequest(url, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap arg0) {
// TODO Auto-generated method stub
iv_image.setImageBitmap(arg0);
}
}, 0, 0, Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
iv_image.setImageResource(mipmap.sym_def_app_icon);
}
});
mApplication.getRequstQueue().add(mRequest);
}
private void initView() {
// TODO Auto-generated method stub
iv_image = (ImageView) findViewById(R.id.iv_imag);
}
}
ImageLoad + LruCache
Lrucache 是图片的内存缓存
public class BitmapCache implements ImageCache{
public LruCache<String, Bitmap> cache;
public BitmapCache() {
// TODO Auto-generated constructor stub
// 拿到最大内存
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// 拿到内存的八分之一来做图片内存缓存
final int cacheSize = maxMemory / 8;
cache =new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
};
}
@Override
public Bitmap getBitmap(String arg0) {
// TODO Auto-generated method stub
return cache.get(arg0);
}
@Override
public void putBitmap(String arg0, Bitmap arg1) {
cache.put(arg0, arg1);
}
}
MainActivity
public class MainActivity extends Activity {
private MyApplication mApplication;
private ImageView iv_image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url ="http://pic.cnblogs.com/avatar/859887/20160120170921.png";
mApplication = new MyApplication();
initView();
BitmapCache bCache = new BitmapCache();
ImageLoader loader = new ImageLoader(mApplication.getRequstQueue(), bCache);
// getImageListener(imageView控件对象,默认图片地址,失败图片地址);
ImageListener listener = ImageLoader.getImageListener(iv_image, R.drawable.ic_launcher, R.drawable.ic_launcher);
// get(图片地址,listener,宽,高);自动帮你处理图片的宽高再也不怕大图片的oom了
loader.get(url, listener,160,160);
}
private void initView() {
// TODO Auto-generated method stub
iv_image = (ImageView) findViewById(R.id.iv_imag);
}
}
Volley还提供的加载图片的控件com.android.volley.NetworkImageView。(这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题,而且NetworkImageView还会根据你对图片设置的width和heigh自动压缩该图片不会产生多的内存,还有NetworkImageView在列表中使用不会图片错误)
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image_view"
android:layout_width="100dp"
android:layout_height="100dp" />
使用方法:
private void networkImageViewUse(NetworkImageView iv, String url) {
ImageLoader imLoader = new ImageLoader(mQueue, new BitmapLruCache());
iv.setDefaultImageResId(R.drawable.ic_launcher);
iv.setErrorImageResId(R.drawable.ic_launcher);
iv.setImageUrl(url, imLoader);
}
我们说了这么多都是请求,那么如何取消请求呢?
1.activity自动销毁时它会自定取消所有请求。
2.给请求设置标签:
request.setTag("My Tag");
取消所有指定标记的请求:
request.cancelAll("My Tag");
有兴趣的可以读下 Volly的架构 主线程啊 网络请求线程 缓存线程
http://blog.csdn.net/superjimmy/article/details/45601661
http://www.15yan.com/story/lHkq4Oi9Y2a/
好了 今天的教程就到这里~
Volly框架的使用基础版及使用中的一些坑 Ace 网络篇(三)的更多相关文章
- 请求网络图片缓存到本地 ,还有一些现成的图片加载框架的使用 Ace网络篇(一)
现在去买年货~~~~~~ 占坑, 现在来填坑 填完睡觉,感谢这俩月的把自己往死里逼得奋斗从JAVA什么都不懂到现在,做这些也是给在自学路上的新人(我也是菜鸟)一点点我力所能及的帮助,等我水平更高了还会 ...
- Swift版iOS游戏框架Sprite Kit基础教程下册
Swift版iOS游戏框架Sprite Kit基础教程下册 试读下载地址:http://pan.baidu.com/s/1qWBdV0C 介绍:本教程是国内唯一的Swift版的Spritekit教程. ...
- Java基础及JavaWEB以及SSM框架学习笔记Xmind版
Java基础及JavaWEB以及SSM框架学习笔记Xmind版 转行做程序员也1年多了,最近开始整理以前学习过程中记录的笔记,以及一些容易犯错的内容.现在分享给网友们.笔记共三部分. JavaSE 目 ...
- 01 基础版web框架
01 基础版web框架 服务器server端python程序(基础版): import socket server=socket.socket() server.bind(("127.0.0 ...
- PHP框架Yii2.0安装(基础版、高级版)
最近农成也是切入了yiiframework 2.0,就是安装yii2.0就花费了不少的时间,为此做了很多的弯路,特此写一篇博文来给后面学习的同学少走一点的弯路.写的不好的地方欢迎各位学习的同学们能够指 ...
- python笔记-19 javascript补充、web框架、django基础
一.JavaScript的补充 1 正则表达式 1.1 test的使用 test 测试是否符合条件 返回true or false 1.2 exec的使用 exec 从字符串中截取匹配的字符 1.3 ...
- 【基础版限时免费】致敬WebForms,ASP.NET Core也能这么玩!
ASP.NET WebForms ASP.NET WebForms 随着微软 2000 年的 .Net Framework 一起发布,至今也将近 20 年的时间.相信很多人和我一样,对 WebForm ...
- J20航模遥控器开源项目系列教程(一)制作教程 | 基础版V1.0发布,从0到1
我们的开源宗旨:自由 协调 开放 合作 共享 拥抱开源,丰富国内开源生态,开展多人运动,欢迎加入我们哈~ 和一群志同道合的人,做自己所热爱的事! 项目开源地址:https://github.com/C ...
- 渗透测试工具BurpSuite做网站的安全测试(基础版)
渗透测试工具BurpSuite做网站的安全测试(基础版) 版权声明:本文为博主原创文章,未经博主允许不得转载. 学习网址: https://t0data.gitbooks.io/burpsuite/c ...
随机推荐
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄
前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传. 在实际开发中,输入输出流用的比较少,但 ...
- widowns 列出文件目录树结构 tree命令
TREE [drive:][path] [/F] [/A] /F 显示每个文件夹中文件的名称.(带扩展名) /A 使用 ASCII 字符,而不使用扩展字符. tree -f > list.t ...
- Web Service和WCF的到底有什么区别
[1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XM ...
- 用memoization优化递归算法[JS/PHP实现]
递归函数,通过把一个大而复杂问题简化为许多但规模较小的问题,以同一个相似模式来计算,降低了解题的难度:通过调用自身函数,极大地减少了函数代码量的优点而为开发者喜爱.但因其不断调用自身函数开辟新栈,且大 ...
- cocos2d-x之计时器初试
bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...
- 设计模式C#实现(七)——生成器模式
生成器模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. UML类图: 构成: 1.Builder(接口/抽象类)定义了创建一个产品Product的各个部件的方法,返回创 ...
- Docker 基础命令 简要入门
本文出自:http://www.cnblogs.com/scoter2008,本文将持续更新所有docker都可以通过man查看帮助:man docker [ps|top|run|...]1.列出正在 ...
- UEdit初始化加载内容偶尔失败,解决
var ue1 = UE.getEditor('aaa',{toolbars: [],autoHeightEnabled: false}); $(function(){ var content =$( ...
- C++STL之迭代器
迭代器 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭代器就如同一个指针.事实上,C++的指针也是一种迭代器.但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值.例如, ...
- linux command intro2 vi
vi cusor : 0 : to the beginning of the current line $ : to the end of the current line G : to the la ...