Android线程(2)——AsyncTask

       在上一篇中,我们简单的介绍了HandlerThread,我们了解到其是一种特殊的与Handler结合使用的一种Thread。今天我们来学习一下Android线程中的另一个知识点AsyncTask,这个词直译过来是异步任务的意思,首先先看一下这个类的官方介绍


AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called begin, doInBackground, processProgress and end.


大概意思是:异步任务能够让我们简单准确的使用UI线程,它可以运行在后台并把最终的运行结果回传给UI线程,整个过程不需要借助(管理)其他的线程或者Handler。

异步任务运行在后台,运行结果回传给UI线程。一个异步任务可以通过三个名为Params,Progress和Result的泛型以及begin,doInBackground,processProgress以及end四步来定义。


到这里,我们对其有一个基本的了解了,总结一句话:其创建的异步任务在后台线程执行,最终的执行结果会回传给UI线程。

 

下面只需要看其如何实现这个目标的即可。

AsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)

Here is an example of subclassing:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }
 Once created, a task is executed very simply:

 new DownloadFilesTask().execute(url1, url2, url3);
 AsyncTask's generic types
The three types used by an asynchronous task are the following:

Params, the type of the parameters sent to the task upon execution. 
Progress, the type of the progress units published during the background computation. 
Result, the type of the result of the background computation. 
Not all types are always used by am asynchronous task. To mark a type as unused, simply use the type Void:

 private class MyTask extends AsyncTask

AsyncTask是一个抽象类,所以其必须被子类化了之后才能实例化使用,通常其子类必须重写doInBackground(),通常还需要重写onPostExecute()。关于三个泛型参数的说明也很详细:

  • Params:发送给即将要执行的异步任务的参数
  • Progress:执行的进度,后台运行
  • Result:后台任务的运行结果

如果其中有的参数没有用到,直接用Void代替即可

上面说到执行一个异步任务通常有四步,下面就来看看这四步的具体实现:

The 4 steps
 When an asynchronous task is executed, the task goes through 4 steps:
 
     onPreExecute(), invoked on the UI thread immediately after the task
     is executed. This step is normally used to setup the task, for instance by
     showing a progress bar in the user interface.

     doInBackground(Params...), invoked on the background thread
     immediately after onPreExecute() finishes executing. This step is used
     to perform background computation that can take a long time. The parameters
     of the asynchronous task are passed to this step. The result of the computation must
     be returned by this step and will be passed back to the last step. This step
     can also use publishProgress(Progress...) to publish one or more units
     of progress. These values are published on the UI thread, in the
     onProgressUpdate(Progress...) step.

     onProgressUpdate(Progress...), invoked on the UI thread after a
     call to publishProgress(Progress...). The timing of the execution is
     undefined. This method is used to display any form of progress in the user
     interface while the background computation is still executing. For instance,
     it can be used to animate a progress bar or show logs in a text field.

     onPostExecute(Result), invoked on the UI thread after the background
     computation finishes. The result of the background computation is passed to
     this step as a parameter.
  • onPreExecute():运行在UI线程,通常用于在异步任务执行前触发界面进度view显示
  • doInBackground():运行在后台线程,主要用于计算任务执行进度,可以通过publishProgress()(本质还是调用onProgressUpdate())实现进度在UI界面的实时显示
  • onProgressUpdate():当publishProgress()被调用的时候其会执行(在UI线程)
  • onPostExecute():当异步任务执行完成后,计算结果会通过result参数回传过来,因为其运行在UI线程,所以运行结果就被传递到了UI线程。

 

        下面就来结合具体的实例来看一下使用,下面就以API给的例子扩展一下,来实现通过异步任务实现下载并在界面实时显示进度的这样一个效果。主要代码如下:

自定义异步任务代码:

package aoto.com.operationasynctask;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

/**
 * author:why
 * created on: 2019/4/15 19:47
 * description:
 */
public class DownloadFilesTask extends AsyncTask<Integer, Integer, Long> {

    private static final String TAG = "DownloadFilesTaskWhy";
    private ProgressBar progressBar;
    private TextView textView;
    private Context context;
    int progress=0;

    public DownloadFilesTask(Context context,ProgressBar progressBar,TextView textView) {
        this.progressBar = progressBar;
        this.context=context;
        this.textView=textView;
    }

    @Override
    protected Long doInBackground(Integer... voids) {

        while(progress<50){
            publishProgress((progress+1));
            try {
                Thread.sleep(100);
                progress++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return Long.valueOf(100);
    }


    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.e(TAG, "onProgressUpdate: " );
        progressBar.setProgress(values[0]);
        textView.setText("已下载:"+values[0]*2+"%");
    }

    @Override
    protected void onPostExecute(Long aLong) {
        Log.e(TAG, "onPostExecute: " );
        Toast.makeText(context,"下载完成",Toast.LENGTH_SHORT).show();
    }

}

测试代码:

package aoto.com.operationasynctask;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

/**
 * @author why
 * @date 2019-4-15 19:43:24
 */
public class MainActivity extends AppCompatActivity {

    DownloadFilesTask task;
    ProgressBar progressBar;
    TextView progressText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar=findViewById(R.id.download_progress_graphic);
        progressText=findViewById(R.id.download_progress_digital);

        task=new DownloadFilesTask(this,progressBar,progressText);
    }


    /**
     * 模拟执行下载文件
     * @param view
     */
    public void download(View view){
        task.execute();
    }

}

AsyncTask本身维护着一个线程池,大小在2-4之间。有一个长度为128的任务队列...里面的很多内容可以之间在该类中查看到

 // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work


 private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

........

具体的使用还是结合文档较好。

注:欢迎扫码关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值