• 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 ...

     

     

     

      

  • 相关阅读:
    android api 中文 (74)—— AdapterView.AdapterContextMenuInfo
    Android API 中文(76)——AdapterView.OnItemLongClickListener
    Android 中文api (81)——InputMethod [输入法]
    android 中文 api (87) —— BaseInputConnection
    Android 中文API合集(4)(102篇)(chm格式)
    Android中文API(97)—— ContextMenu
    android api 中文 (75)—— AdapterView.OnItemClickListener
    android 中文api (84) —— TrafficStats
    Windows XP 上安装 Bind9
    数据库索引实例之三
  • 原文地址:https://www.cnblogs.com/syyh2006/p/9505481.html
Copyright © 2020-2023  润新知