zoukankan      html  css  js  c++  java
  • Android AsyncTask分析

    ---恢复内容开始---

    因为android的UI线程是不安全的,如果你UI线程里执行一些耗时任务,很容易就导致程序崩溃。并且目前网络任务也不能够在UI线程里执行。处理这些问题除了直接写一个线程以外,Android还提供一个AsyncTask(异步任务类)来更简单的处理一些耗时任务。

    AsyncTask<>是一个抽象类,通常用于继承,继承时需要指定三个泛型参数。

    1、Params:启动任务时传入的参数的类型。这是一个数组,可以传多个参数。调用时使用params[0]、params[1]、params[2]来获取。

    2、Progress:后台任务完成的进度值的类型。

    3、Result:后台任务执行完毕返回结果的类型。

    使用AsyncTask需要如下三步:

    1、继承抽象类,实现一个子类,传入三个泛型参数。如果有参数不需要使用可设为Void。

    2、根据需要,可实现以下方法。

    • doInBackground(Params...):该方法是必须的,这个方法下写的是后台线程要执行的任务,并且会在子线程运行(其他方法都是在UI线程执行)。。该方法可以调用publicProgress(Progress...values)方法更新任务的进度。
    • onProgressUpdate(Progress... values):该方法在上一步调用publicProgress时触发。
    • onPreExecute():该方法会在执行doInBackground方法前执行,用于做一些准备工作。
    • onPostExecute(Result result):当doInBackground执行结束之后,系统会自动调用该方法,返回值也会传到此函数。我们可以在这里完成后台线程执行后的结果。

    3、最后用新建我们继承类后的结果,然后调用execute(Params... params)。

      注意:对象必须在UI线程中创建、execute方法必须在UI线程中调用、以上四个方法都需系统自动调用、每个对象只能被执行一次,多次调用引发异常。

    实例

    讲了那么多铺垫,让我们来讲个例子吧~

    我现在想从互联网上下载一张图片,就使用这个AsyncTask来做一下吧~

     为让所有方法都实现一次,我们用两种方法实现:1、下载完毕后直接进行显示。2、一边加载一边显示进度,加载完毕显示图片。

    下面是第一种的代码,相对简单一点,只用了两个函数。

    public class MainActivity extends Activity {
        
        int downloadSize;
        int fileSize;
        
        Button bn;
        ImageView iv;
        ProgressBar progressBar;
        String url = "http://ww1.sinaimg.cn/mw690/6aa88161gw1eqqbw7h821j20hs0hsaba.jpg";
        
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            bn = (Button) findViewById(R.id.down);
            iv = (ImageView) findViewById(R.id.image);
            
            MyOnClickListener myOnClickListener = new MyOnClickListener();
            bn.setOnClickListener(myOnClickListener);
        }
        
        class MyOnClickListener implements android.view.View.OnClickListener{
            
            @Override
            public void onClick(View v) {
                
                AsyncDownload asyncDownload = new AsyncDownload();
                asyncDownload.execute(url);
            }        
        }
        
        class AsyncDownload extends AsyncTask<String, Integer, Bitmap>
        {
            
            @Override
            protected Bitmap doInBackground(String... params) {
    
                String imageUrl = params[0];
                
                URL url;
                try {
                    url = new URL(imageUrl);
                    InputStream is = url.openStream();
                    BitmapFactory.Options op = new BitmapFactory.Options();
                    op.inSampleSize = 2;
                    Bitmap bitmap = BitmapFactory.decodeStream(is, null,
                            op);
                    
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
            
            @Override
            protected void onPostExecute(Bitmap result) {
                super.onPostExecute(result);
                
                iv.setImageBitmap(result);
            }
      }
    }

    上面的代码的功能是点击按钮,然后doInBackground后台下载图片,下载完毕onPostExecute显示图片。仅仅使用了两个函数,但是实现了AsyncTask的核心功能。

    然后让我们感受一下能够显示进度的。

    public class MainActivity extends Activity {
        
        int downloadSize;
        int fileSize;
        
        Button bn;
        ImageView iv;
        ProgressBar progressBar;
        String url = "http://ww1.sinaimg.cn/mw690/6aa88161gw1eqqbw7h821j20hs0hsaba.jpg";
        
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            bn = (Button) findViewById(R.id.down);
            iv = (ImageView) findViewById(R.id.image);
            progressBar = (ProgressBar) findViewById(R.id.bar);
            
            MyOnClickListener myOnClickListener = new MyOnClickListener();
            bn.setOnClickListener(myOnClickListener);
        }
        
        Handler handler = new Handler(){
            
            public void handleMessage(android.os.Message msg) 
            {
                
            }
        };
        
        class MyOnClickListener implements android.view.View.OnClickListener{
            
            @Override
            public void onClick(View v) {
                
                AsyncDownload asyncDownload = new AsyncDownload();
                asyncDownload.execute(url);
            }        
        }
        
        class AsyncDownload extends AsyncTask<String, Integer, Void>
        {
            
            @Override
            protected Void doInBackground(String... params) {
    
                String imageUrl = params[0];
                
                try {
                    URL url = new URL(imageUrl);
                    URLConnection conn = url.openConnection(); 
                    conn.connect(); 
                    InputStream is = conn.getInputStream(); 
                    fileSize = conn.getContentLength(); 
                    
                    publishProgress(0x111);
                    
                    FileOutputStream fos = new FileOutputStream(getPath());
                    byte[] bytes = new byte[1024]; 
                    int len = -1; 
                    while((len = is.read(bytes))!=-1) 
                    { 
                        fos.write(bytes, 0, len); 
                        downloadSize+=len; 
                        publishProgress(0x222);
                    } 
                    publishProgress(0x333);
                    is.close(); 
                    fos.close(); 
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null; 
            }
            
            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
                
                switch(values[0])
                {
                case 0x111:
                    progressBar.setMax(fileSize);
                    break;
                case 0x222:
                    progressBar.setProgress(downloadSize);
                    break;
                case 0x333:
                    try { 
                        if(getPath().endsWith(".jpg")||getPath().endsWith(".png")){ 
                            FileInputStream fis = new FileInputStream(getPath()); 
                            iv.setImageBitmap(BitmapFactory.decodeStream(fis)); 
                        } 
                        downloadSize = 0; 
                        fileSize = 0; 
                    } catch (FileNotFoundException e) { 
                        e.printStackTrace(); 
                    } catch (IOException e) { 
                        e.printStackTrace(); 
                    } 
                    break;
                }
            }
        }
        
        public String getPath() {
            File root = getExternalCacheDir();
            if (root != null)
            {
                return root.getAbsolutePath()  + "test.jpg";
            }
            
            return null;
        }
    }

    这里实现的功能是点击下载按钮,后台从互联网加载文件,首先获取文件大小,设置progressbar最大值,然后一边下载、一边存入本地、一边设置progressbar的值,实现进度条。下载完毕从本地获取图片显示出来。这一次多使用了显示进度的函数onProgressUpdate。

    其实,onProgressUpdate这个函数一般我们在线程里会用Handler来实现。

    在AsyncTask给我们把平常使用线程进行异步操作的所用东西打包在一起了,不得不说确实省了一些事。

    实际上能够用AsyncTask实现的东西完全可以直接用线程来实现~

    我在些第二个代码的时候写顺了手,用Handler实现了一遍,大家在下面可以看一下。

    public class MainActivity extends Activity {
        
        int downloadSize;
        int fileSize;
        
        Button bn;
        ImageView iv;
        ProgressBar progressBar;
        String url = "http://ww1.sinaimg.cn/mw690/6aa88161gw1eqqbw7h821j20hs0hsaba.jpg";
        
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            bn = (Button) findViewById(R.id.down);
            iv = (ImageView) findViewById(R.id.image);
            progressBar = (ProgressBar) findViewById(R.id.bar);
            
            MyOnClickListener myOnClickListener = new MyOnClickListener();
            bn.setOnClickListener(myOnClickListener);
        }
        
        Handler handler = new Handler(){
            
            public void handleMessage(android.os.Message msg) 
            {
                switch(msg.what)
                {
                case 0x111:
                    progressBar.setMax(fileSize);
                    break;
                case 0x222:
                    progressBar.setProgress(downloadSize);
                    break;
                case 0x333:
                    try { 
                        if(getPath().endsWith(".jpg")||getPath().endsWith(".png")){ 
                            FileInputStream fis = new FileInputStream(getPath()); 
                            iv.setImageBitmap(BitmapFactory.decodeStream(fis)); 
                        } 
                        downloadSize = 0; 
                        fileSize = 0; 
                    } catch (FileNotFoundException e) { 
                        e.printStackTrace(); 
                    } catch (IOException e) { 
                        e.printStackTrace(); 
                    } 
                    break;
                }
            }
        };
        
        class MyOnClickListener implements android.view.View.OnClickListener{
            
            @Override
            public void onClick(View v) {
                
                AsyncDownload asyncDownload = new AsyncDownload();
                asyncDownload.execute(url);
            }        
        }
        
        class AsyncDownload extends AsyncTask<String, Integer, Void>
        {
            
            @Override
            protected Void doInBackground(String... params) {
    
                String imageUrl = params[0];
                
                try {
                    URL url = new URL(imageUrl);
                    URLConnection conn = url.openConnection(); 
                    conn.connect(); 
                    InputStream is = conn.getInputStream(); 
                    fileSize = conn.getContentLength(); 
                    
                    handler.sendEmptyMessage(0x111);
                    
                    FileOutputStream fos = new FileOutputStream(getPath());
                    byte[] bytes = new byte[1024]; 
                    int len = -1; 
                    while((len = is.read(bytes))!=-1) 
                    { 
                        fos.write(bytes, 0, len); 
                        downloadSize+=len; 
                        handler.sendEmptyMessage(0x222);
                    } 
                    handler.sendEmptyMessage(0x333);
                    is.close(); 
                    fos.close(); 
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null; 
            }
        }
        
        public String getPath() {
            File root = getExternalCacheDir();
            if (root != null)
            {
                return root.getAbsolutePath()  + "test.jpg";
            }
            
            return null;
        }
    }

    啦啦啦,就到这里吧~

  • 相关阅读:
    8.2.8 A Simple Game
    8.2.7 Be the Winner
    8.2.6 John
    8.2.5 kiki's game
    8.2.2 Good Luck in CET-4 Everybody!
    8.2.4 悼念512汶川大地震遇难同胞——选拔志愿者
    8.1.8 Team Queue
    8.2.1 Brave Game
    8.1.7 愚人节的礼物
    8.1.6 Windows Message Queue
  • 原文地址:https://www.cnblogs.com/glimpse/p/5280942.html
Copyright © 2011-2022 走看看