Volley是在Google I/O 2013上发布的网络通信框架,是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。特别适用于数据量不大但是通信频繁的场景。
其中蓝色部分代表主线程,绿色部分代表缓存线程,橙色部分代表网络线程。我们在主线程中调用RequestQueue的add()方法来添加一条网络请求,这条请求会先被加入到缓存队列当中,如果发现可以找到相应的缓存结果就直接读取缓存并解析,然后回调给主线程。如果在缓存中没有找到结果,则将这条请求加入到网络请求队列中,然后处理发送HTTP请求,解析响应结果,写入缓存,并回调主线程。
我们使用Volley发送一个GET请求或者POST请求,来连接网络。也可以来加载一个网络图片等。
首先我们在布局中加入两个按钮,一个用来点击请求网络连接,一个用来点击加载网络图片,这里加载的图片我们用NetworkImageView显示,在布局中引入是必须写全名。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button_img" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="显示网络图片"/>
<com.android.volley.toolbox.NetworkImageView android:id="@+id/networkimg" android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="连接网络"/>
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
首先获得RequestQueue对象queue,然后创建StringRequest对象request,最后调用queue.add(request)方法即可。
①GET请求
RequestQueue queue= Volley.newRequestQueue(getApplicationContext());
StringRequest request=new StringRequest(Request.Method.GET, "http://www.baidu.com", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
textView.setText(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
textView.setText("网络连接错误!");
}
});
queue.add(request);
②POST请求,我们向自己搭建的服务器提交数据
RequestQueue queue= Volley.newRequestQueue(getApplicationContext());
StringRequest request=new StringRequest(Request.Method.POST, "http://192.168.0.30:8080/MyWebTest/MyTestServerlet", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
textView.setText(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
textView.setText("网络连接错误!");
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> map=new HashMap<String, String>();
map.put("username","ytttttttttttt");
return map;
}
};
queue.add(request);
注意这里我们每点击一次按钮都会创建一个新的请求队列,势必会占用较多内存空间,所以我们这里做了一下封装。
………………源码如下…………….
import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
/** * Created by Administrator on 2015/9/14. */
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
…………………….源码……………………
这里我们再发送请求时,
只需用一句代码:
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(request);
①再说加载网络图片最简单的使用ImageRequest,创建StringRequest对象request,具体用法与上边StringRequest的用法一样,最后调用queue.add(request)方法即可。
②因为我们用的是NetworkImageView,所以特别简单的就能加载我们的网络图片。得到我们的networkImageView,然后调用setImageUrl()方法,传入网络图片的URL,和ImageLoader对象即可。
NetworkImageView networkImageView= (NetworkImageView) findViewById(R.id.networkimg);
networkImageView.setImageUrl("http://p1.yokacdn.com/pic/star/pic/2012/U230P1T117D617446F5956DT20120410152548_maxw808.jpg",MySingleton.getInstance(getApplicationContext()).getImageLoader());
③如果我们使用的是ImageView来加载我们的网络图片,具体的步骤如下:
1. 创建一个RequestQueue对象。
2. 创建一个ImageLoader对象。
3. 获取一个ImageListener对象。
4. 调用ImageLoader的get()方法加载网络上的图片。
因为前两步我们已经在MySingleton类中已经封装好了,所以我们只需在点击事件中加入下面代码即可:
ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
ImageLoader imageLoader=MySingleton.getInstance(getApplicationContext()).getImageLoader(); imageLoader.get("http://p1.yokacdn.com/pic/star/pic/2012/U230P1T117D617446F5956DT20120410152548_maxw808.jpg",listener);
上边在得到ImageListener对象时传入的3个参数,第一个是展示网络图片的ImageView对象,第二个是在加载过程中显示图片,第三个时加载失败时显示的图片。然后得到ImageLoader对象,调用get()方法,方法中传入两个参数,第一个是网络图片的URL,第二个就是创建的ImageListener对象。
最后别忘了要声明访问网络的权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
XUtils是Android快速开发框架,支持大文件上传,有更全面的http请求协议支持,最低兼容android 2.2 (api level 8)。
XUtils目前有四大模块:DbUtils,ViewUtils,HttpUtils和BitmapUtils
这里我们还是主要讲一下网络连接HttpUtils。
RequestCallBack<T>()
的匿名类,因为RequestCallBack是一个抽象类,所以必须实现里边的两个抽象方法onSuccess()和onFailure()。RequestCallBack<T>()
的匿名类,与GRT请求相同。我们在布局中加入两个按钮,一个用于发送GET请求,一个用于发送POST请求
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button_xutils_get" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Xutils_get"/>
<Button android:id="@+id/button_xutils_post" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Xutils_post"/>
<ScrollView android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
MainActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.view.annotation.ViewInject;
public class MainActivity extends AppCompatActivity {
@ViewInject(R.id.textview)
private TextView textView;//注解,省去findViewById
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//textView= (TextView) findViewById(R.id.textview);
ViewUtils.inject(this);
Button button_get= (Button) findViewById(R.id.button_xutils_get);
button_get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
HttpUtils httpUtils=new HttpUtils();
httpUtils.send(HttpRequest.HttpMethod.GET, "http://www.baidu.com", new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
textView.setText(responseInfo.result);
}
@Override
public void onFailure(HttpException e, String s) {
textView.setText("连接失败!");
}
});
}
});
Button button_post= (Button) findViewById(R.id.button_xutils_post);
button_post.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
HttpUtils httpUtils=new HttpUtils();
RequestParams params=new RequestParams();
params.addBodyParameter("username", "ytttttt");
httpUtils.send(HttpRequest.HttpMethod.POST, "http://192.168.0.30:8080/MyWebTest/MyTestServerlet", params, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
textView.setText(responseInfo.result);
}
@Override
public void onFailure(HttpException e, String s) {
textView.setText("连接失败!");
}
});
}
});
}
}
注意:上面代码中我们可以在控件上边写上注解@ViewInject()
,传入该控件的ID,就省去了findViewById()方法带来的大量的麻烦。不过后边我们要调用一下ViewUtils.inject(this);
这个方法!
最后,别忘了声明访问网络的权限
<uses-permission android:name="android.permission.INTERNET" />