zoukankan      html  css  js  c++  java
  • android:异步任务asyncTask介绍及异步任务下载图片(带进度条)

    为什么要用异步任务?

    在android中仅仅有在主线程才干对ui进行更新操作。而其他线程不能直接对ui进行操作

    android本身是一个多线程的操作系统,我们不能把全部的操作都放在主线程中操作 。比方一些耗时操作。

    假设放在主线程中 会造成堵塞 而当堵塞事件过长时 系统会抛出anr异常。所以我们要使用异步任务。android为我们提供了一个封装好的组件asynctask。

    AsyncTask能够在子线程中更新ui,封装简化了异步操作。适用于简单的异步处理。假设多个后台任务时就要使用Handler了 在这里就不再说明。

    AsyncTask通经常使用于被继承。AsyncTask定义了三种泛型类型<Params,Progress,Result>

    Params:启动任务时输入的參数类型

    Progress:后台任务运行的百分比

    Result:运行任务完毕后返回结果的类型

    继承AsyncTask后要重写的方法有:

    doInBackgroud:必须重写,异步运行后台线程要完毕的任务,耗时任务要写在这里,而且在这里不能操作ui。能够调用 publishProgress方法来更新实时的任务进度

    onPreExecute:运行耗时操作前调用,能够完毕一些初始化操作

    onPostExecute:在doInBackground 运行完毕后。主线程调用此方法。能够在此方法中操作ui

    onProgressUpdate:在doInBackgroud方法中调用publishProgress方法,更新任务的运行进度后 就会调用这种方法

    以下通过一个实例来了解AsyncTask

    首先附上执行结果


    布局文件:

    <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" >
    
        <Button
            android:id="@+id/btn_download"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="点击下载" />
    
        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >
    
            <ImageView
                android:id="@+id/iv_image"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:scaleType="fitCenter" />
    
        </FrameLayout>
    
    </LinearLayout>
    MainActivity

    package com.example.asynctask;
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URLConnection;
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity implements OnClickListener{
    	
    	private ImageView image;
    	private ProgressDialog progress;
    	private Button btn_download;
    	private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg";
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		image=(ImageView) findViewById(R.id.iv_image);
    		btn_download=(Button) findViewById(R.id.btn_download);
    		progress=new ProgressDialog(this);
    		progress.setIcon(R.drawable.ic_launcher);
    		progress.setTitle("提示信息");
    		progress.setMessage("正在下载,请稍候...");
    		progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    		btn_download.setOnClickListener(this);
    	}
    	
    	@Override
    	public void onClick(View v) {
    		// TODO Auto-generated method stub
    		new MyAsyncTask().execute(URL);
    	}
    	/*
    	 * String*********相应我们的URL类型
    	 * Integer********进度条的进度值
    	 * BitMap*********异步任务完毕后返回的类型  
    	 * */
    	class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{
    		
    		//运行异步任务(doInBackground)之前运行。而且在ui线程中运行
    		@Override
    		protected void onPreExecute() {
    			// TODO Auto-generated method stub
    			super.onPreExecute();
    			if(image!=null){
    				image.setVisibility(View.GONE);
    			}
    			//開始下载 对话框进度条显示
    			progress.show();
    			progress.setProgress(0);
    		}
    		
    		@Override
    		protected Bitmap doInBackground(String... params) {
    			// TODO Auto-generated method stub
    			//params是一个可变长的数组 在这里我们仅仅传进来了一个url 
    			String url=params[0];
    			Bitmap bitmap=null;
    			URLConnection connection;
    			InputStream is;//用于获取数据的输入流
    			ByteArrayOutputStream bos;//能够捕获内存缓冲区的数据,转换成字节数组。
    			int len;
    			float count=0,total;//count为图片已经下载的大小 total为总大小
    			try {
    				//获取网络连接对象
    				connection=(URLConnection) new java.net.URL(url).openConnection();
    				//获取当前页面的总长度
    				total=(int)connection.getContentLength();
    				//获取输入流
    				is=connection.getInputStream();
    				bos=new ByteArrayOutputStream();
    				byte []data=new byte[1024];
    				while((len=is.read(data))!=-1){
    					count+=len;
    					bos.write(data,0,len);
    					//调用publishProgress发布进度,最后onProgressUpdate方法将被运行
    					publishProgress((int)(count/total*100));
    					//为了显示出进度 人为休眠0.5秒
    					Thread.sleep(500);
    				}
    				bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length);
    				is.close();
    				bos.close();
    			} catch (MalformedURLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			return bitmap;
    		}
    		//在ui线程中运行 能够操作ui
    		@Override
    		protected void onPostExecute(Bitmap bitmap) {
    			// TODO Auto-generated method stub
    			super.onPostExecute(bitmap);
    			//下载完毕 对话框进度条隐藏
    			progress.cancel();
    			image.setImageBitmap(bitmap);
    			image.setVisibility(View.VISIBLE);
    		}
    		
    		/*
    		 * 在doInBackground方法中已经调用publishProgress方法 更新任务的运行进度后
    		 * 调用这种方法 实现进度条的更新
    		 * */
    		@Override
    		protected void onProgressUpdate(Integer... values) {
    			// TODO Auto-generated method stub
    			super.onProgressUpdate(values);
    			progress.setProgress(values[0]);
    		}
    	}
    }
    

    最后不要忘记在AndroidManifest文件里配置网络訪问权限

    	<uses-permission android:name="android.permission.INTERNET"/>


  • 相关阅读:
    group_concat函数与find_in_set()函数相结合
    PHP获取指定时间的上个月
    CI框架 数据库批量插入 insert_batch()
    PHP可变长函数方法介绍
    js闭包理解
    Android百度地图开发(一)之初体验
    Activity的四种启动模式和onNewIntent()
    再探Java基础——throw与throws
    Failed to load JavaHL Library解决方法
    Eclipse中添加Android系统jar包
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7102221.html
Copyright © 2011-2022 走看看