zoukankan      html  css  js  c++  java
  • Android的AsyncTask

                                                                                      Android之AsyncTask
    1.AsyncTask从引用的包(package android.os)可以看出,它是Android给我们提供的一个处理异步任务的类.通过此类,可以实现异步处理最后完成UI更新.
    2.对于Android UI更新,只能在主线程进程更新,此原因已经在前面(Android的消息机制Handler)介绍,所以剩下只能通过子线程或者异步进行更新.对于子线程进行更新,前面已经介绍,此处只介绍异步方法进行的更新.
    3.对于为什么用异步更新,以及是否会降级ui性能,那么可以肯定的说如果不用异步处理一些耗时操作,新建立一个线程同样也会消耗资源,同样也会耗时.而且对于子线程必须做到和ui同步,即ui销毁前要对线程进行处理,否则很容易出现空指针或者ui已经结束子线程还在跑的情况.而对于异步处理是不会出现此情况的.下面会针对说明.
    4.AsyncTask介绍:
      (1)public abstract class AsyncTask<Params, Progress, Result>
         Params:起动任务即异步处理的参数doInBackground(Params... params)
         Progress:后台任务执行中返回进度值的类型,onProgressUpdate(Progress... values)
         Result:后台任务执行完成后返回结果的类型,onPostExecute(Result result)
      (2)一些方法说明:
         onPreExecute:执行后台之前,需要的一些初始化,此方法隶属主线程
         doInBackground:异步任务处理处,耗时操作在此方法完成,此方法的执行在子线程完成.
                     onPostExecute:当doInBackground方法完成后,系统自动调用此方法,且将doInBackground方法返回的值传入此方法进行ui的更新,此方法隶属主线程.
         onProgressUpdate:在doInBackground方法中调用publishProgress方法更新任务执行进度后,将回调用此方法,通过此方法可以知道任务进展.
            publishProgress:此方法是发布进度的时候使用,当异步方法doInBackground调用此方法后,onProgressUpdate会被回调.
           (3)publishProgress此方法的工作源码可以说明异步处理为什么是安全的:
         

    @WorkerThread
         protected final void publishProgress(Progress... values) {
             if (!isCancelled()) {
                 getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                         new AsyncTaskResult<Progress>(this, values)).sendToTarget();
             }
         }
    
    
         private static Handler getMainHandler() {
             synchronized (AsyncTask.class) {
                 if (sHandler == null) {
                     sHandler = new InternalHandler(Looper.getMainLooper());
                 }
                 return sHandler;
             }
         }
    
         private static class InternalHandler extends Handler {
             public InternalHandler(Looper looper) {
                 super(looper);
             }
    
             @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
             @Override
             public void handleMessage(Message msg) {
                 AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
                 switch (msg.what) {
                     case MESSAGE_POST_RESULT:
                         // There is only one result
                         result.mTask.finish(result.mData[0]);//执行的这个方法就是当前AsyncTask自身的finish()这个方法。而这正是说明了在正常执行完工作线程的doInBackground()之后再在主线程中执行finish()
                         break;
                 }
             }
         }


    整个过程可以说明在更新进度的时候,会上对象锁(AsyncTask.class),在执行完异步后再在线程中执行finish方法,那么此时将不会有不界面销毁的时候组件还在work的情况.

    5.下面通过demo演示一个典型的异步处理实力:加载图片。

    package com.example.testactivityb;
    
     import java.io.BufferedInputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import java.net.URL;
     import java.net.URLConnection;
     import android.os.AsyncTask;
     import android.os.Bundle;
     import android.app.Activity;
     import android.graphics.Bitmap;
     import android.graphics.BitmapFactory;
     import android.util.Log;
     import android.view.Menu;
     import android.view.View;
     import android.widget.ImageView;
     import android.widget.TextView;
    
     public class MainActivity extends Activity {
         private ImageView imageView ;
         private TextView textView;
         private static String URL = "http://pic1.sc.chinaz.com/files/pic/pic9/201808/zzpic13515.jpg";
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
             imageView = (ImageView) findViewById(R.id.image);
             textView = (TextView)findViewById(R.id.textView);
             textView.setText("hello world,after a moment,it will disapear");
             Log.d(this.toString(), "onCreate main thread ");
             //通过调用execute方法开始处理异步任务.相当于线程中的start方法.
             new MyAsyncTask().execute(URL);
         }
         @Override
         public boolean onCreateOptionsMenu(Menu menu) {
             // Inflate the menu; this adds items to the action bar if it is present.
             getMenuInflater().inflate(R.menu.activity_main, menu);
             return true;
         }
         class MyAsyncTask extends AsyncTask<String,Void,Bitmap> {
             //onPreExecute:异步处理前的操作,此方法依然在主线程中
            @Override
             protected void onPreExecute() {
                 super.onPreExecute();
                 Thread.dumpStack();
                 Log.d(this.toString(), "onPreExecute ...");
                 //此处将textView设置为可见,仅表示在此可以设置ui相关的操作
                textView.setVisibility(View.VISIBLE);
             }
    
             //doInBackground:进行异步任务处理,另开了线程.
             @Override
             protected Bitmap doInBackground(String... params) {
                 Log.d(this.toString(), "doInBackground ...");
                 //获取传进来的参数
                String url = params[0];
                 Bitmap bitmap = null;
                 URLConnection connection ;
                 InputStream inputStream ;
                 try {
                     connection = new URL(url).openConnection();//url对象用openconnection()打开连接,获得URLConnection类对象,再用URLConnection类对象的connect()方法进行连接 
                    inputStream = connection.getInputStream();//an input stream that reads from this open connection
                     //为了更清楚的看到加载图片的等待操作,将子线程休眠下.
                     Thread.sleep(4000);  
                     BufferedInputStream bis = new BufferedInputStream(inputStream);
                     bitmap = BitmapFactory.decodeStream(bis);//通过decodeStream方法解析输入流
                    inputStream.close();
                     bis.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 return bitmap;
             }
    
             //onPostExecute用于UI的更新.此方法的参数为doInBackground方法返回的值.
             @Override
             protected void onPostExecute(Bitmap bitmap) {
                 super.onPostExecute(bitmap);
                 Log.d(this.toString(), "onPostExecute ...");
                 //对UI进行操作,此时Bitmap是doInBackground处理后的结果.
                textView.setVisibility(View.GONE);
                 imageView.setImageBitmap(bitmap);
             }
         }   
     }

    执行过程如下:

     08-16 10:38:04.102  8437  8437 D AccessibilityManager: getInstance() new sInstance = android.view.accessibility.AccessibilityManager@a9d45fb, context = com.example.testactivityb.MainActivity@b6b7618, userId = 0
     08-16 10:38:04.159  8437  8437 D com.example.testactivityb.MainActivity@b6b7618: onCreate main thread 
     08-16 10:38:04.161  8437  8437 D com.example.testactivityb.MainActivity$MyAsyncTask@7e9fcb7: onPreExecute ...
     08-16 10:38:04.166  8437  8450 D com.example.testactivityb.MainActivity$MyAsyncTask@7e9fcb7: doInBackground ...
     08-16 10:38:04.285  1475  1536 I ActivityManager: Displayed com.example.testactivityb/.MainActivity: +318ms
     08-16 10:38:08.506  8437  8437 D com.example.testactivityb.MainActivity$MyAsyncTask@7e9fcb7: onPostExecute ...

     

     

     

      

  • 相关阅读:
    matlab cell
    matlab linux 快捷键设置——有问题还是要解决
    latex 小结
    TOJ 1258 Very Simple Counting
    TOJ 2888 Pearls
    HDU 1248 寒冰王座
    TOJ 3486 Divisibility
    TOJ 3635 过山车
    TOJ 1840 Jack Straws
    HDU 4460 Friend Chains
  • 原文地址:https://www.cnblogs.com/syyh2006/p/9505481.html
Copyright © 2011-2022 走看看