当前位置: 首页 > news >正文

wordpress过FTP更新建站合肥网络公司seo

wordpress过FTP更新,建站合肥网络公司seo,网站,商城,app 建设,网站建设管理视频简介 Android中只能在主线程中进行UI操作,如果是其它子线程,需要借助异步消息处理机制Handler。除此之外,还有个非常方便的AsyncTask类,这个类内部封装了Handler和线程池。本文先简要介绍AsyncTask的用法,然后分析具体…

简介

Android中只能在主线程中进行UI操作,如果是其它子线程,需要借助异步消息处理机制Handler。除此之外,还有个非常方便的AsyncTask类,这个类内部封装了Handler和线程池。本文先简要介绍AsyncTask的用法,然后分析具体实现。

基本用法

AsyncTask是一个抽象类,我们需要创建子类去继承它,并且重写一些方法。AsyncTask接受三个泛型参数:

  • Params: 指定传给任务执行时的参数的类型
  • Progress: 指定后台任务执行时将任务进度返回给UI线程的参数类型
  • Result: 指定任务完成后返回的结果的类型

除了指定泛型参数,还需要根据需要重写一些方法,常用的如下:

  • onPreExecute(): 这个方法在UI线程调用,用于在任务执行前做一些初始化操作,如在界面上显示加载进度控件
  • doInBackground: 在onPreExecute()结束之后立刻在后台线程调用,用于耗时操作。在这个方法中可调用publishProgress方法返回任务的执行进度
  • onProgressUpdate: 在doInBackground调用publishProgress后被调用,工作在UI线程
  • onPostExecute: 后台任务结束后被调用,工作在UI线程

源码分析

下面分析这个类的实现,主要有线程池以及Handler两部分。

线程池

当执行一个AsyncTask的时候调用的是execute()方法,就从这个开始看:

public final AsyncTask<Params, Progress, Result> execute(Params... params){return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,  Params... params) {  if (mStatus != Status.PENDING) {  switch (mStatus) {  case RUNNING:  throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED:  throw new IllegalStateException("Cannot execute task:"  + " the task has already been executed "  + "(a task can be executed only once)");    }  }  mStatus = Status.RUNNING;  //先执行 onPreExecuteonPreExecute();  mWorker.mParams = params;  exec.execute(mFuture);  return this; 
} 

execute方法会调用executeOnExecutor。在这个方法中先检查任务是否已经执行或者执行结束,然后把任务标记为running。最开始执行的是onPreExecute,接着把参数赋值给mWorker对象。这个mWorker是一个Callable对象,最终被包装为FutureTask,代码如下:

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {  Params[] mParams;  
} mWorker = new WorkerRunnable<Params, Result>() {  public Result call() throws Exception {  mTaskInvoked.set(true);  Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  //noinspection unchecked  return postResult(doInBackground(mParams));  }  };mFuture = new FutureTask<Result>(mWorker) {  @Override  protected void done() {  try {  postResultIfNotInvoked(get());  } catch (InterruptedException e) {  android.util.Log.w(LOG_TAG, e);  } catch (ExecutionException e) {  throw new RuntimeException("An error occured while executing doInBackground()",  e.getCause());  } catch (CancellationException e) {  postResultIfNotInvoked(null);  }  }  
}; 

从上面的代码可以看出,在mWorker对象中的call()方法会调用doInbackground,返回值交给postResult方法,这个方法通过Handler发送消息,这一点稍后再详细分析。

mWorker对象被封装成FutureTask之后交由线程池执行,从execute方法可以看出,使用的是sDefaultExecutor,它的值默认为SERIAL_EXECUTOR,也就是串行执行器,实现如下:

 private static class SerialExecutor implements Executor {  //线性双向队列,用来存储所有的AsyncTask任务  final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();  //当前正在执行的AsyncTask任务  Runnable mActive;  public synchronized void execute(final Runnable r) {  //将新的AsyncTask任务加入到双向队列中  mTasks.offer(new Runnable() {  public void run() {  try {  //执行AsyncTask任务  r.run();  } finally {  //当前任务执行结束后执行下一个任务scheduleNext();  }  }  });    if (mActive == null) {  scheduleNext();  }  }  protected synchronized void scheduleNext() {  //从任务队列中取出队列头部的任务,如果有就交给并发线程池去执行  if ((mActive = mTasks.poll()) != null) {  THREAD_POOL_EXECUTOR.execute(mActive);  }  }  
}public static final Executor THREAD_POOL_EXECUTOR  = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,  TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);    

在上面的代码中,如果有任务执行,那么SerialExecutorexecute方法会被调用,它的逻辑是把Runnable对象加入ArrayDeque队列中,然后判断mActivie是否为空。第一次执行时mActive当然为空,所以执行scheduleNext,其实就是取出任务队列中的第一个任务交给线程池(THREAD_POOL_EXECUTOR)执行。加入mTask队列的Runnable对象的run方法里最终一定会调用scheduleNext,那么又会从任务队列中取出队头任务执行。这样便实现了单线程顺序执行任务,所以在AsyncTask默认启用的是单线程执行,只有上一个任务执行后才会执行下一个任务。如果想要启用多线程执行任务,可以直接调用 executeOnExecutor(Executor exec, Params... params),这里的Executor参数可以使用AsyncTask自带的THREAD_POOL_EXECUTOR,也可以自己定义。

Handler

AsyncTask内部用Handler传递消息,它的实现如下:

private static class InternalHandler extends Handler {  @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]);  break;  case MESSAGE_POST_PROGRESS:  result.mTask.onProgressUpdate(result.mData);  break;  }  }  
} 

如果消息类型是任务执行后的返回值(MESSAGE_POST_RESULT)将调用finish()方法:

private void finish(Result result) {  if (isCancelled()) {  onCancelled(result);  } else {  onPostExecute(result);  }  mStatus = Status.FINISHED;  
} 

从上面可以知道,如果任务取消了,将调用onCancelled,否则调用onPostExecute,所以一个AsyncTask任务如果取消了,那么onPostExecute将不会得到执行。

如果消息类型是执行进度(MESSAGE_POST_PROGRESS)将调用onProgressUpdate,这个方法默认是空方法,我们可以根据自己的需要重写。

总结

AsyncTask的主要逻辑就如上面所分析的,总结几个需要注意的地方:

  • AsyncTask的类必须在UI线程加载(从4.1开始系统会帮我们自动完成)
  • AsyncTask对象必须在UI线程创建
  • execute方法必须在UI线程调用
  • 不要手动调用onPreExecute()doInBackgroundonProgressUpdate方法
  • 一个任务只能被调用一次(第二次调用会抛出异常)
  • 多个 AsyncTask 默认是串行执行,可以改为并发执行,但要注意资源同步的问题。
  • 大量 AsyncTask 任务填满线程池的队列会抛出异常。

其它还有一些细节可以自行研究源码,另外推荐几篇不错的文章:

  1. Android源码分析—带你认识不一样的AsyncTask
  2. Android AsyncTask完全解析,带你从源码的角度彻底理解
http://www.lbrq.cn/news/2797075.html

相关文章:

  • 装饰公司看的设计网站百度客户端官网
  • 班级网站开发报告seo推广外包报价表
  • 彭阳县城乡与住房建设局网站搜狗站长工具
  • 哪个网站简历做的好淘大象排名查询
  • 网店托管公司seo网络营销
  • 关键词排名优化提升培训百度竞价优化
  • 汉化主题做网站效果图强力搜索引擎
  • 事业单位网站建设方案关键词提取工具
  • 做知乎网站的图片东莞seo整站优化火速
  • 商城网站建设合同烟台seo网络推广
  • 广西网站建设介绍百度seo通科
  • 网站建设自己怎么做最强大的搜索引擎
  • 四川建设厅官方网站查询网站推广优化外包公司哪家好
  • 网站世界排名怎么做谁有恶意点击软件
  • 做外贸哪些b2b网站比较有效重庆seo技术教程博客
  • 做网站编辑好还是美工好网上卖产品怎么推广
  • 做的好的奥运会网站seo免费资源大全
  • 大连市城乡建设局网站付费推广
  • 闵行18路seo属于什么职位类型
  • 做服装设计兼职的网站深圳百度网站排名优化
  • 白云建设网站微信营销技巧
  • 国外设计网站 绿色的北京企业网站推广哪家公司好
  • 常熟高端网站建设搜索引擎推广步骤
  • 微网站如何做推广淘宝app官方下载
  • 欧美风格企业网站人工智能培训班收费标准
  • 网站建设软文谷歌推广开户多少费用
  • 做封面的免费网站品牌公关
  • 网站建设方案评标原则网络推广专员岗位职责
  • 做游戏制作 网站产品关键词怎么找
  • 高端品牌网站建设定位不需要验证码的广告平台
  • 【框架篇二】FastAPI路由与请求处理
  • 8.21IPSEC安全基础后篇,IKE工作过程
  • 机器学习聚类算法
  • 使用C++17标准 手写一个vector
  • PowerShell脚本检查业务健康状态
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(17):文法+单词第5回3-复习