android异步任务 访问网络 加载图片 解决方案大集合
1. Handler + Thread 异步执行任务
- 在UI线程中开启子线程,使用Handler 发消息,通知主线程更新UI
- 直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错误:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容。
所有的UI线程要去负责View的创建并且维护它,例如更新冒个TextView的显示,都必须在主线程中去做,我们不能直接在UI线程中去创建子线程,要利用消息机制:handler,如下就是handler的简单工作原理图:
文章图片
public class HandlerTestActivity extends Activity {
private TextView tv;
private static final int UPDATE = 0;
private Handler handler = new Handler() {@Override
public void handleMessage(Message msg) {
// TODO 接收消息并且去更新UI线程上的控件内容
if (msg.what == UPDATE) {
// Bundle b = msg.getData();
// tv.setText(b.getString("num"));
tv.setText(String.valueOf(msg.obj));
}
super.handleMessage(msg);
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.tv);
new Thread() {
@Override
public void run() {
// TODO 子线程中通过handler发送消息给handler接收,由handler去更新TextView的值
try {
for (int i = 0;
i < 100;
i++) {
Thread.sleep(500);
Message msg = new Message();
msg.what = UPDATE;
// Bundle b = new Bundle();
// b.putString("num", "更新后的值:" + i);
// msg.setData(b);
msg.obj = "更新后的值:" + i;
handler.sendMessage(msg);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}}
-------------请求网络数据-----------------------------------
new Thread() {
@Override
public void run() {
// 使用 okHttp 请求网络
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(SERVERURL).build();
try {
Response response = okHttpClient.newCall(request).execute();
String result = response.body().string();
Message msg = new Message();
msg.what = 0;
Bundle bundle = new Bundle();
bundle.putString("result", result);
msg.setData(bundle);
handler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
2. AsyncTask抽象类 (一个异步任务框架)
- 更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可。
- android提供了一套专门用于异步处理的类。即:AynsTask类。使用这个类可以为耗时程序开辟一个新线程进行处理,处理完时返回。
其实,AsynTask类就是对Thread类的一个封装,并且加入了一些新的方法。编程时,两者都可以实现同样的功能。本文后面将对AsynTask和Thread进行比较
AsyncTask抽象类
//在主线程调用该方法
private void useAsyncTask() {
/*主线程调用AsynTask子类实例的execute()方法后,首先会调用onPreExecute()方法。
onPreExecute()在主线程中运行,可以用来写一些开始提示代码。*/
DownLoader downLoader = new DownLoader(textView);
/*execute()向doInBackground()传递。*/
downLoader.execute(SERVERURL);
}
//Params:启动任务执行的输入参数的类型。 //Progress:后台任务完成进度值的类型。 //Result:后台执行任务完成后返回结果的类型
class DownLoader extends AsyncTask {
TextView text;
public DownLoader(TextView text) {
this.text = text;
}/*处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理*/
@Override
protected String doInBackground(String... params) {String url = params[0];
String result = null;
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
result = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
/*//publishProgress()为AsyncTask类中的方法
//常在doInBackground()中调用此方法
//用于通知主线程,后台任务的执行情况.
//此时会触发AsyncTask中的onProgressUpdate()方法*//* doInBackground()的返回值会传递给onPostExecute()。*/
return result;
}@Override
protected void onCancelled(String s) {
super.onCancelled(s);
}/*onProgressUpdate()方法用于更新异步执行中,在主线程中处理异步任务的执行信息参数为publishProgress() 方法的参数*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}/*处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理*/
@Override
protected void onPostExecute(String s) {
//super.onPostExecute(s);
text.setText(s);
}/*之后启动新线程,调用doInBackground()方法,进行异步数据处理。*/
@Override
protected void onPreExecute() {
super.onPreExecute();
System.out.println("开始执行异步任务.....");
}/*onCancelled()方法用于异步任务被取消时,在主线程中执行相关的操作*/
@Override
protected void onCancelled() {
super.onCancelled();
}
}
参考链接 ; http://blog.csdn.net/guolin_blog/article/details/9526203
网络加载框架 Volley Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框
参考链接: http://blog.csdn.net/guolin_blog/article/details/17482095/
* 它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
volley 在android studio中如何使用
文章图片
- StringRequest的用法
private void uesVolley() {
/*1. 创建一个RequestQueue对象。
2. 创建一个StringRequest对象。
3. 将StringRequest对象添加到RequestQueue里面。
*/
/**
* 注意这里拿到的RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,
* 然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常合适高并发的,
* 因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,
* 基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。
*/
RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
/**
* 这里new出了一个StringRequest对象,StringRequest的构造函数需要传入三个参数,
* 第一个参数就是目标服务器的URL地址
* 第二个参数是服务器响应成功的回调,
* 第三个参数是服务器响应失败的回调
*/
StringRequest stringRequest = new StringRequest("http://www.baidu.com", new com.android.volley.Response.Listener() {
@Override
public void onResponse(String response) {
textView.setText(response);
Log.d("TAG", response);
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {}
});
//最后,将这个StringRequest对象添加到RequestQueue里面就可以了
mQueue.add(stringRequest);
/**
* TTP的请求类型通常有两种,GET和POST,刚才我们使用的明显是一个GET请求,那么如果想要发出一条POST请求应该怎么做呢?
* StringRequest中还提供了另外一种四个参数的构造函数,其中第一个参数就是指定请求类型的
*/
StringRequest stringRequestPost = new StringRequest(com.android.volley.Request.Method.POST, SERVERURL,
successListener, errorLiatener) {
@Override
protected Map getParams() throws AuthFailureError {HashMap map = new HashMap<>();
map.put("useName", "admin");
map.put("password", "123456");
return map;
}
};
mQueue.add(stringRequestPost);
}
- JsonRequest的用法
学完了最基本的StringRequest的用法,我们再来进阶学习一下JsonRequest的用法。类似于StringRequest,JsonRequest也是继承自Request类的,不过由于JsonRequest是一个抽象类,因此我们无法直接创建它的实例,那么只能从它的子类入手了。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest,从名字上你应该能就看出它们的区别了吧?一个是用于请求一段JSON数据的,一个是用于请求一段JSON数组的。
至于它们的用法也基本上没有什么特殊之处,先new出一个JsonObjectRequest对象
/*JsonRequest的用法*/
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(SERVERURL, null,
new com.android.volley.Response.Listener() {
@Override
public void onResponse(JSONObject response) {
textView.setText(response.toString());
Log.e("JsonObject",response.toString());
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {}
});
mQueue.add(jsonObjectRequest);
- ImageRequest的用法
private void loadImage() {RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
ImageRequest imageRequest =new ImageRequest("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png",
new com.android.volley.Response.Listener() {
@Override
public void onResponse(Bitmap response) {
image.setImageBitmap(response);
}
},
0, 0, Bitmap.Config.RGB_565,
new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {}
});
mQueue.add(imageRequest);
}
可以看到,ImageRequest的构造函数接收六个参数,第一个参数就是图片的URL地址,这个没什么需要解释的。第二个参数是图片请求成功的回调,这里我们把返回的Bitmap参数设置到ImageView中。第三第四个参数分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩,指定成0的话就表示不管图片有多大,都不会进行压缩。第五个参数用于指定图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小。第六个参数是图片请求失败的回调,这里我们当请求失败时在ImageView中显示一张默认图片。
最后将这个ImageRequest对象添加到RequestQueue里就可以了
- ImageLoader的用法
由于ImageLoader已经不是继承自Request的了,所以它的用法也和我们之前学到的内容有所不同,总结起来大致可以分为以下四步:
- 创建一个RequestQueue对象。
- 创建一个ImageLoader对象。
- 获取一个ImageListener对象。
- 调用ImageLoader的get()方法加载网络上的图片。
private void loadImage() {/*,ImageLoader的构造函数接收两个参数,第一个参数就是RequestQueue对象,第二个参数是一个ImageCache对象*/
ImageLoader imageLoader = new ImageLoader(mQueue, new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {
return null;
}@Override
public void putBitmap(String url, Bitmap bitmap) {}
});
/*我们通过调用ImageLoader的getImageListener()方法能够获取到一个ImageListener对象,
getImageListener()方法接收三个参数,
第一个参数指定用于显示图片的ImageView控件,
第二个参数指定加载图片的过程中显示的图片,
第三个参数指定加载图片失败的情况下显示的图片*/
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(image,
R.mipmap.ic_launcher,
R.mipmap.ic_download);
/*get()方法接收两个参数,第一个参数就是图片的URL地址,第二个参数则是刚刚获取到的ImageListener对象。
当然,如果你想对图片的大小进行限制,也可以使用get()方法的重载,指定图片允许的最大宽度和高度*/
imageLoader.get(imageUrl,imageListener,200,200);
}
- NetworkImageView
1. 创建一个RequestQueue对象。
2. 创建一个ImageLoader对象。
3. 在布局文件中添加一个NetworkImageView控件。
4. 在代码中获取该控件的实例。
5. 设置要加载的图片地址。
xml文件
java代码
private void useNetworkImageView() {RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
/*,ImageLoader的构造函数接收两个参数,第一个参数就是RequestQueue对象,第二个参数是一个ImageCache对象*/
ImageLoader imageLoader = new ImageLoader(mQueue, new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {
return null;
}@Override
public void putBitmap(String url, Bitmap bitmap) {}
});
ivNetWorkImage.setDefaultImageResId(R.mipmap.ic_download);
ivNetWorkImage.setErrorImageResId(R.mipmap.ic_launcher);
ivNetWorkImage.setImageUrl(imageUrl, imageLoader);
}
LruCache android Studio 使用 butterknife 注解功能
- 需要添加下面一行依赖
compile 'com.jakewharton:butterknife:7.0.1'
Picasso 图片缓存框架
- 使用:
依赖中搜索 Picasso ,点击添加 - picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,
可以实现图片下载和缓存功能。仅仅只需要一行代码就能完全实现图片的异步加载
参考链接: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0731/1639.html
- 简单用例—从网络加载:
/**
* 图片下载的步骤:
* 1、使用异步任务或者 handler+thread 获取图片资源
* 2、使用bitmapFactory 对图片进行解码
* 3、显示图片
*/
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Picasso
.with(MainActivity.this)
.load(imageUrl)//有多个重载方法
.placeholder(R.mipmap.ic_launcher)//,默认显示图片
.error(R.mipmap.ic_launcher)//加载错误时显示的图片
.resize(80,80)//转换图片以适应布局大小并减少内存占用
.centerCrop()
//.transform(new CustomeCropAquareTransFormation()) //自定义转换
.into(imageView);
//显示到指定控件上
}
});
//自定义裁剪,将 CustomeCropSquareTransformation 的对象传递给transform 方法即可 public class CustomeCropAquareTransFormation implements Transformation{@Override
public Bitmap transform(Bitmap bitmap) {
int size = Math.min(bitmap.getWidth(),bitmap.getHeight());
//得到 Width 和 Height 的最小值
//判断以高度进行缩减还是以高度进行缩减
int x= (bitmap.getWidth()-size)/2;
int y = (bitmap.getHeight()-size)/2;
Bitmap resultBitmap = Bitmap.createBitmap(bitmap, x, y, 80, 80);
//从原始位图剪切图像
if(resultBitmap!=bitmap){
bitmap.recycle();
//回收Bitmap资源
}
return resultBitmap;
}@Override
public String key() {
return "square";
}
}
load() 有多个重载方法 也可以从 从Android Resources 中加载 , 从本地File文件中加载 , 从URI地址中加载
- Picasso不仅实现了图片异步加载的功能,还解决了android中加载图片时需要解决的一些常见问题:
1.在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。2.使用复杂的图片压缩转换来尽可能的减少内存消耗3.自带内存和硬盘二级缓存功能
public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
从原始位图剪切图像,这是一种高级的方式。可以用Matrix(矩阵)来实现旋转等高级方式截图
参数说明:
Bitmap source:要从中截图的原始位图int x:起始x坐标int y:起始y坐标int width:要截的图的宽度int height:要截的图的宽返回值:返回一个剪切好的Bitmap
Universal ImageLoader github: https://github.com/nostra13/Android-Universal-Image-Loader
参考链接1: http://blog.csdn.net/vipzjyno1/article/details/23206387
参考链接2: http://blog.csdn.net/wwj_748/article/details/10079311/
参考链接:Android-Universal-Image-Loader三大组件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration详解
UIL是是一个开源项目,其目的就是提供一个可重复使用的仪器为异步图像加载、缓存和显示。它的使用很简单:
尽管Picasso拥有更好的API,但其缺乏自定义。而使用UIL构建器几乎可以配置所有(其中最重要的就是在抓取和缓存大型图片时,Picasso会失败)。
简单描述一下这个项目的结构:每一个图片的加载和显示任务都运行在独立的线程中,除非这个图片缓存在内存中,这种情况下图片会立即显示。如果需要的图片缓存在本地,他们会开启一个独立的线程队列。如果在缓存中没有正确的图片,任务线程会从线程池中获取,因此,快速显示缓存图片时不会有明显的障碍。(别人那边借鉴的这段)
流程图:
文章图片
- 使用前配置:
mainf 中添加权限
- 重点有三个重要的类:
/**
* 全局配置 ImageLoaderConfiguration
* 先要配置ImageLoaderConfiguration这个类实现全局ImageLoader的实现情况。
*/
public class MyApplecation extends Application {@Override
public void onCreate() {
super.onCreate();
ImageLoaderConfiguration config;
config = new ImageLoaderConfiguration
.Builder(MyApplecation.this)
.memoryCacheExtraOptions(480,800)// max width, max height,即保存的每个缓存文件的最大长宽
//.diskCacheExtraOptions()
.threadPoolSize(3)//线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY-2)
.denyCacheImageMultipleSizesInMemory()
//.memoryCache(new UsingFreqLimitedMemoryCache(2*1024*1024))//你可以通过自己的内存缓存实现
.memoryCacheSize(2*1024*1024)//内存缓存大小
.diskCacheSize(50*1024*1024)//磁盘缓存大小
//.diskCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密
.tasksProcessingOrder(QueueProcessingType.FIFO)//设置线程池队列任务,为FIFO(先进先出)
.diskCacheFileCount(100)//设置磁盘缓存的文件最大数量
//.diskCache(new UnlimitedDiskCache(cacheDir))// 自定义缓存路径
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())//显示的图片的各种格式DisplayImageOptions 的设置
.imageDownloader(new BaseImageDownloader(MyApplecation.this,5*1000,30*1000))
.writeDebugLogs()// Remove for release app
.build();
//构建完成//配置好ImageLoaderConfiguration后,调用以下方法来实现初始化:
ImageLoader.getInstance().init(config);
class BaseImageDowner implements ImageDownloader {@Override
public InputStream getStream(String imageUri, Object extra) throws IOException {
return null;
}
}
}
}
DisplayImageOptions 用于指导每一个Imageloader根据网络图片的状态(空白、下载错误、正在下载)显示对应的图片,是否将缓存加载到磁盘上,下载完后对图片进行怎么样的处理
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ic_launcher)//设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.weixin)//设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.feng3)//设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)//设置下载的图片是否缓存在内存中
.cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中
.considerExifParams(true)//是否考虑JPEG图像EXIF参数(旋转,翻转)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED) //设置图片以如何的编码方式显示
.bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型
//.delayBeforeLoading(1000)//int delayInMillis为你设置的下载前的延迟时间//.preProcessor(BitmapProcessor preProcessor)//设置图片加入缓存前,对bitmap进行设置
.resetViewBeforeLoading(true)// 设置图片在下载前是否重置,复位
.displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少
.displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
.build();
ImageLoader :是具体下载图片,缓存图片,显示图片的具体执行类,它有两个具体的方法displayImage(…)、loadImage(…),但是其实最终他们的实现都是displayImage(…)
displayImage(…) 方法有多个重载
1.使用默认配置
// imageUrl代表图片的URL地址,imageView代表承载图片的IMAGEVIEW控件ImageLoader.getInstance().displayImage(imageUrl, imageView);
2.加载自定义配置的一个图片的
// imageUrl代表图片的URL地址,imageView代表承载图片的IMAGEVIEW控件 , options代表DisplayImageOptions配置文件ImageLoader.getInstance().displayImage(imageUrl, imageView,options);
- 图片加载时候带加载情况的监听
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
//开始加载的时候执行
}
@Override
public void onLoadingFailed(FailReason failReason) {
//加载失败的时候执行
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
//加载成功的时候执行
}
@Override
public void onLoadingCancelled() {
//加载取消的时候执行}});
- 图片加载时候,带监听又带加载进度条的情况
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
//开始加载的时候执行
}
@Override
public void onLoadingFailed(FailReason failReason) {
//加载失败的时候执行
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
//加载成功的时候执行
}
@Override
public void onLoadingCancelled() {
//加载取消的时候执行
},new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current,int total) {
//在这里更新 ProgressBar的进度信息
}
});
如何加载本地图片:正确配置 ImageUrl 的地址即可
String imageUri = "http://site.com/image.png";
// from Web
String imageUri = "file:///mnt/sdcard/image.png";
// from SD card
String imageUri = "content://media/external/audio/albumart/13";
// from content provider
String imageUri = "assets://image.png";
// from assets
String imageUri = "drawable://" + R.drawable.image;
// from drawables (only images, non-9patch)
xUtils 异步框架的使用 –
github: https://github.com/wyouflf/xUtils3
xUtils3简介
- xUtils 包含了很多实用的android工具.
- xUtils 支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响…
- xUtils 最低兼容Android 4.0 (api level 14). (Android 2.3?)
- xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本:
- HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略.
- 支持标准的Cookie策略, 区分domain, path…
- 事件注解去除不常用的功能, 提高性能.
- 数据库api简化提高性能, 达到和greenDao一致的性能.
- 图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转…
compile 'org.xutils:xutils:3.3.36'
使用前配置 需要的权限
初始化
// 在application的onCreate中初始化
@Override
public void onCreate() {
super.onCreate();
x.Ext.init(this);
x.Ext.setDebug(BuildConfig.DEBUG);
// 是否输出debug日志, 开启debug会影响性能.
...
}
加载图片 最简单的使用默认配置加载图片
x.image().bind(imageView,imageUrl);
//使用xUtils加载图片,默认自带缓存
x.image().bind() 方法有多个重载函数,这一点和ImageLoader 很相似
void bind(ImageView view, String url);
void bind(ImageView view, String url, ImageOptions options);
void bind(ImageView view, String url, Callback.CommonCallback callback);
void bind(ImageView view, String url, ImageOptions options, Callback.CommonCallback callback);
【android异步任务 访问网络 加载图片 解决方案大集合】使用示例:
ImageOptions options = new ImageOptions.Builder().setSize(DensityUtil.dip2px(120), DensityUtil.dip2px(120))//图片大小
.setRadius(DensityUtil.dip2px(5))//ImageView圆角半径
.setCrop(true)// 如果ImageView的大小不是定义为wrap_content, 不要crop.
.setImageScaleType(ImageView.ScaleType.CENTER_CROP)
.setLoadingDrawableId(R.mipmap.ic_launcher)//加载中默认显示图片
.setFailureDrawableId(R.mipmap.ic_launcher)//加载失败后默认显示图片.build();
x.image().bind(imageView,imageUrl);
//使用xUtils加载图片,默认自带缓存
x.image().bind(imageView,imageUrl,options,new MyCallBack());
/**
* 加载图片时的回调函数
*/
class MyCallBack implements Callback.CommonCallback {@Override
public void onSuccess(Object result) {
System.out.println("加载图片"+"onSuccess()");
}@Override
public void onError(Throwable ex, boolean isOnCallback) {}@Override
public void onCancelled(CancelledException cex) {}@Override
public void onFinished() {
System.out.println("加载图片"+"onFinished()");
}
xUtils的网络请求
RequestParams params = new RequestParams("http://blog.csdn.net/mobile/experts.html");
x.http().get(params, new Callback.CommonCallback() {
@Override
public void onSuccess(String result) {
System.out.println("网络请求onSuccess()...");
text.setText(result);
}@Override
public void onError(Throwable ex, boolean isOnCallback) {}@Override
public void onCancelled(CancelledException cex) {}@Override
public void onFinished() {
System.out.println("网络请求onFinished()...");
}
});
带有缓存的请求示例:
RequestParams params = new RequestParams("http://blog.csdn.net/mobile/experts.html");
// 默认缓存存活时间, 单位:毫秒.(如果服务没有返回有效的max-age或Expires)
params.setCacheMaxAge(1000 * 60 * 10);
// 接下来使用CacheCallback, xUtils将为该请求缓存数据.
x.http().get(params, new Callback.CacheCallback() {
@Override
public boolean onCache(String result) {
// 得到缓存数据, 缓存过期后不会进入这个方法.
// 如果服务端没有返回过期时间, 参考params.setCacheMaxAge(maxAge)方法.
//
// * 客户端会根据服务端返回的 header 中 max-age 或 expires 来确定本地缓存是否给 onCache 方法.
//如果服务端没有返回 max-age 或 expires, 那么缓存将一直保存, 除非这里自己定义了返回false的
//逻辑, 那么xUtils将请求新数据, 来覆盖它.
//
// * 如果信任该缓存返回 true, 将不再请求网络;
----这里可以和刷新配合使用
//返回 false 继续请求网络, 但会在请求头中加上ETag, Last-Modified等信息,
//如果服务端返回304, 则表示数据没有更新, 不继续加载数据.
//
text.setText(result);
return false;
// true: 信任缓存数据, 不在发起网络请求;
false不信任缓存数据.
}@Override
public void onSuccess(String result) {
// 注意: 如果服务返回304 或 onCache 选择了信任缓存, 这时result为null.
if (result != null) {
text.setText(result);
}
}@Override
public void onError(Throwable ex, boolean isOnCallback) {}@Override
public void onCancelled(CancelledException cex) {}@Override
public void onFinished() {// 成功获取数据,在此方法中对返回的数据进行操作}
});
}
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- 多线程NSOperation
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)