异步处理任务工具类(AsyncTask)实现多张图片的下载(已知url)
2016-09-17 19:14
579 查看
异步加载任务机制是为了处理多个对象同时对主线程操作而出现的,作用和handler是相似的,在后台进行操作之后,可以更改UI。但他的实现方式比handler容易许多。 AsycTask中通过四个方法实现功能:onPreExecute();在执行具体操作之前执行,可以进行一些操作的初始化;onPostExecute();更新操作完成之后执行;doInBackground;具体的逻辑操作,不会修改UI,将更改操作传送给onProgressUpdate;onProgressUpdate();负责执行更新UI的操作;除了doInbackground是子线程,其他的都是主线程。 本例涉及知识点:I/O流,异步处理任务,动态加载控件;所用文件为数据截取软件截取出来的相关的图片url和名字文件。 一,使用表格布局进行展示,将图片和文字进行封装到一个布局中,在代码中动态加载; 二,使用scrollView包裹表格布局,实现内容的滑动; 三,使用asynctask实现图片的批量加载到布局中;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" > <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true">//使scrollview里面的元素填满布局,使用fill-parent没用 <GridLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/gridlayout" android:columnCount="3"> </GridLayout> </ScrollView> </RelativeLayout>
其中,scrollview中的fillviewport属性为使布局填满屏幕,在此处使用fill-parent没用; 首先,布局的初始化:
public class Main6Activity extends AppCompatActivity { GridLayout gridLayout;//表格布局,加载relativelayout RelativeLayout[]relativeLayouts;//动态加载relativelayout的数组 TextView[]textViews;//存放textview ImageView[]imageViews;//存放imageview int width,height; List<String>carName;//存放截取出来的车的名字 List<String>carLogo;//存放截取出来的车的URL @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main6); carName = new ArrayList<>(); carLogo = new ArrayList<>(); gridLayout = (GridLayout) findViewById(R.id.gridlayout);
第一步:流操作实现图片URL和名字的获取
private void readInfo(){ InputStream inputStream=null; try { inputStream = getResources().getAssets().open("car.txt"); StringBuilder builder = new StringBuilder(); Reader reader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(reader); String temp=null; while((temp=bufferedReader.readLine())!=null){ builder.append(temp); } String carInfo=builder.toString(); String[] carsInfo = carInfo.split("###"); for(String car:carsInfo){ String [] cars=car.split("#"); carName.add(cars[0]); carLogo.add(cars[1]); } int n=carLogo.size(); relativeLayouts = new RelativeLayout ; textViews = new TextView ; imageViews = new ImageView ; } catch (IOException e) { e.printStackTrace(); } }
relativelayout和textview以及imageview是动态的加载,所以使用数组来表现;大小为截取之后的carname的大小; 第二步,初始化布局,以及动态加载布局;
private void initView(){ for(int n=0;n<relativeLayouts.length;n++){ RelativeLayout relativeLayout = new RelativeLayout(this); ImageView imageView = new ImageView(this); imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); imageView.setImageResource(R.mipmap.ic_launcher); TextView textView = new TextView(this); textView.setText(carName.get(n)); textView.setTextColor(Color.parseColor("#2c2c2c")); textView.setTextSize(20); textView.setBackgroundColor(Color.parseColor("#ffffff")); relativeLayouts =relativeLayout; imageViews = imageView; textViews = textView; relativeLayout.addView(textView,width,height); relativeLayout.addView(imageView,width,height/3); gridLayout.addView(relativeLayout); } }
使用add方法将布局加载到布局之中。
第三步。异步处理任务工具类处理图片下载:
图片URL保存在list集合carLogo中,将集合作为参数传入进行逻辑操作;参数为string类型,在oncreate方法中,将集合转换为数组,然后传入asynctask
String []carlogo = new String[carLogo.size()]; carlogo = carLogo.toArray(carlogo); new downLoadImage().execute();
doInBackground方法中网络下载图片,
URL url = new URL(params[i]); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); InputStream inputStream = httpURLConnection.getInputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int len=0; byte[] bytes = new byte[1024]; while((len=inputStream.read(bytes))!=-1){ byteArrayOutputStream.write(bytes,0,len); }
然后转换为图片对象;
byte[] image = byteArrayOutputStream.toByteArray(); Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
重点内容
问题一:此时如果直接将bitmap对象穿过去,会发生意想不到的效果,会发生图片和名字不对应的情况。原因是:doInBackground是子线程,而更改UI是主线程,发生了线程抢占资源的情况,而加锁不太好,具体原因不是很明白;所以给的解决方法是用一个map集合来维护。根据map集合的键值相对性。
HashMap<Integer, Bitmap> hashMap = new HashMap<>(); hashMap.put(i, bitmap); publishProgress(hashMap);
publishProgress是将逻辑操作的结果发送到主线程进行UI的修改;
onProgressUpdate负责修改UI;
根据键取出相应的值,然后imageview负责修改;
protected void onProgressUpdate(HashMap<Integer, Bitmap>... values) { Set<Integer> keys = values[0].keySet(); Iterator<Integer>it=keys.iterator(); while(it.hasNext()){ int position=it.next(); Bitmap bitmap = values[0].get(position); imageViews[position].setImageBitmap(bitmap); } }
运行结果如下:
demo附上,有意愿的可以探讨一下~;
异常处理任务工具类之多图片下载
相关文章推荐
- 用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)
- AsyncTask异步任务与LruCache缓存策略实现图片加载(一)
- android:异步任务asyncTask介绍及异步任务下载图片(带进度条)
- Android 异步任务——AsyncTask (附使用AsyncTask下载图片Demo)
- AsyncTask --异步任务+简单的网络图片下载
- Android带进度条的下载图片示例(AsyncTask异步任务)
- 一个异步任务接收两个url下载两个图片
- AsyncTask 异步任务下载文字or图片
- 使用异步任务-AsyncTask下载远程图片
- 安卓中异步任务实现带下载进度的根据图片地址下载图片
- android:异步任务asyncTask介绍及异步任务下载图片(带进度条)
- AsyncTask 异步任务下载网络图片
- 异步任务Asynctask实现图片墙
- Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩
- 网络相册:Gallery+AsyncTask+URLConnection 实现异步加载网络图片
- Android之AsyncTask异步任务下载网络图片
- 用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具
- 网络相册:Gallery+AsyncTask+URLConnection 实现异步加载网络图片
- android学习笔记---使用AsyncTask实现异步处理,内部使用线程加Handler
- AsyncTask下载图片异步更新UI