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

找聊城做网站网站你应该明白我的意思吗

找聊城做网站,网站你应该明白我的意思吗,视频背景网站,兰州旅游攻略Android 多线程----AsyncTask异步任务详解 【正文】 本文将讲解一下Android的多线程的知识#xff0c;以及如何通过AsyncTask机制来实现线程之间的通信。 一、Android当中的多线程#xff1a; 在Android当中#xff0c;当一个应用程序的组件启动的时候#xff0c;并且没有其… Android 多线程----AsyncTask异步任务详解 【正文】 本文将讲解一下Android的多线程的知识以及如何通过AsyncTask机制来实现线程之间的通信。 一、Android当中的多线程 在Android当中当一个应用程序的组件启动的时候并且没有其他的应用程序组件在运行时Android系统就会为该应用程序组件开辟一个新的线程来执行。默认的情况下在一个相同Android应用程序当中里面的组件都是运行在同一个线程里的这个线程称之为Main线程。当我们通过某个组件来启动另一个组件的时候这个时候默认都是在同一个线程当中完成的。当然我们可以自己来管理我们的Android应用的线程我们可以根据我们自己的需要来给应用程序创建额外的线程。 二、Main Thread 和 Worker Thread 在Android当中通常将线程分为两种一种叫做Main Thread除了Main Thread之外的线程都可称为Worker Thread。 当一个应用程序运行的时候Android操作系统就会给该应用程序启动一个线程这个线程就是我们的Main Thread这个线程非常重要它主要用来加载UI界面完成系统和用户之间的交互并将交互后的结果又展示给用户所以Main Thread又被称为UI Thread。 Android系统默认不会给应用程序组件创建一个额外的线程所有的这些组件默认都是在同一个线程中运行。然而某些时候当我们的应用程序需要完成一个耗时操作的时候如访问网络或者是对数据库进行查询此时UI Thread就会被阻塞。例如当我们点击一个Button然后希望其从网络中获取一些数据如果此操作在UI Thread当中完成的话UI线程就会处于阻塞的状态此时我们的系统不会调度任何其它的事件更糟糕的是当我们的整个现场如果阻塞时间超过5秒钟(官方描述)这个时候就会出现 著名的ANR (Application Not Responding)的问题此时应用程序会弹出一个框让用户选择是否退出该程序。对于Android开发来说出现ANR的现象是绝对不能被允许的。 另外由于Android UI控件不是线程安全的所以我们不能在UI Thread之外的线程当中对UI控件进行操作。因此在Android的多线程编程当中有两条非常重要的原则必须遵守 不能在UI Thread当中进行耗时操作以免阻塞UI Thread不能在UI Thread之外的线程当中操纵UI元素  三、如何处理UI Thread 和 Worker Thread之间的通信 我们既不能在主线程当中处理耗时的操作又不能在工作线程中来访问我们的UI控件那么我们比如从网络中要下载一张图片又怎么能将其更新到UI控件上呢这就关系到了主线程和工作线程之间的通信问题了。在Android当中提供了异步消息处理机制的两种方式来解决线程之间的通信问题一种是通过Handler的机制(这种方式在后面的博客中将详细介绍),还有一种就是今天要详细讲解的 AsyncTask 机制。 四、AsyncTask AsyncTask异步任务从字面上来说就是在UI主线程运行的时候异步完成一些操作。AsyncTask允许我们在后台执行一个异步任务。我们可以将耗时的操作放在异步任务当中来执行并随时将任务执行的结果返回给UI线程来更新UI控件。通过AsyncTask我们可以轻松解决多线程之间的通信问题。 怎么来理解AsyncTask呢通俗来说AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架其介于Thread和Handler之间我们如果要定义一个AsyncTask就需要定义一个类来继承AsyncTask这个抽象类并实现其唯一的一个 doInBackgroud 抽象方法。 要掌握AsyncTask我们就必须要一个概念总结起来就是: 3个泛型4个步骤。 我们来看看AsyncTask这个抽象类的定义当我们定义一个类来继承AsyncTask这个类的时候需要为其指定3个泛型参数 AsyncTask Params, Progress, Result Params: 指定的是我们传递给异步任务执行时的参数的类型Progress: 指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型Result: 指定的是异步任务执行完后返回给UI线程的结果的类型  我们在定义一个类继承AsyncTask类的时候必须指定好这三个泛型的类型如果都不指定的话则都将其写成Void例如 AsyncTask Void, Void, Void 4个步骤当我们执行一个异步任务时需要按照下面的4个步骤分别执行 onPreExecute(): 这个方法是在执行异步任务之前的时候执行并且是在UI Thread当中执行的通常我们在这个方法里做一些UI控件的初始化的操作例如弹出ProgressDialogdoInBackground(Params... params): 在onPreExecute()方法执行完后会马上执行这个方法这个方法就是来处理异步任务的方法Android操作系统会在后台的线程池当中开启一个worker thread来执行这个方法即在worker thread当中执行执行完后将执行结果发送给最后一个 onPostExecute 方法在这个方法里我们可以从网络当中获取数据等一些耗时的操作onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的在异步任务执行的时候有时需要将执行的进度返回给UI界面例如下载一张网络图片我们需要时刻显示其下载的进度就可以使用这个方法来更新进度。这个方法在调用之前我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将进度时时刻刻传递给 onProgressUpdate 方法来更新onPostExecute(Result... result): 当异步任务执行完之后就会将结果返回给这个方法这个方法也是在UI Thread当中调用的我们可以将返回的结果显示在UI控件上  为什么AsyncTask抽象类只有一个 doInBackground 的抽象方法呢原因是我们如果要做一个异步任务我们必须要为其开辟一个新的Thread让其完成一些操作而在完成这个异步任务时我可能并不需要弹出ProgressDialog并不需要随时更新ProgressDialog的进度条也并不需要将结果更新给UI界面所以除了 doInBackground 方法之外的三个方法都不是必须有的因此必须要实现的方法是 doInBackground 方法。 4个步骤简洁版描述如下   第一步表示任务执行前的操作   第二步主要完成耗时操作   第三步主要是更新UI操作   第四步产生最终结果 以下实例中代表的含义为   第一步显示进度条   第二步此任务必不可少在后台执行任务将进度值传给第三步将结果传给第四步   第三步进度值更新   第四步产生最终结果   五、【实例】通过AsyncTask来从网络上下载一张图片 下面通过两个代码示例来看看如何通过AsyncTask来从网络上下载一张图片并更新到ImageView控件上。 在这之前必须要执行的操作是添加网络授权。下面的例子将有详细的操作描述。 【实例一】从网络下载图片弹出一个ProgressDialog但不显示实时进度 1、添加网络授权 因为手机默认不能访问网络所以首先要在清单文件 AndroidManifest.xml中添加网络授权。 加上uses-permission android:nameandroid.permission.INTERNET/ 2、完整版代码如下 activity_main.xml的代码 RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:paddingBottomdimen/activity_vertical_marginandroid:paddingLeftdimen/activity_horizontal_marginandroid:paddingRightdimen/activity_horizontal_marginandroid:paddingTopdimen/activity_vertical_margintools:context.MainActivity ImageViewandroid:idid/imageView1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_alignParentToptrueandroid:layout_centerHorizontaltrue /Buttonandroid:idid/button1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_alignParentBottomtrueandroid:layout_centerHorizontaltrueandroid:layout_marginBottom136dpandroid:text下载网络图片 / /RelativeLayoutMainActivity.java的代码 package com.example.downloadimage01; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity {private ImageView imageView ;private Button button ; private ProgressDialog dialog ;//来自网络的图片private String image_path http://imgsrc.baidu.com/forum/pic/item/7c1ed21b0ef41bd51a5ac36451da81cb39db3d10.jpg ;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//添加弹出的对话框dialog new ProgressDialog(this) ;dialog.setTitle(提示) ;dialog.setMessage(正在下载图片请稍后···) ;imageView (ImageView)findViewById(R.id.imageView1) ;button (Button)findViewById(R.id.button1) ;button.setOnClickListener(new OnClickListener() {Overridepublic void onClick(View v) {//点击按钮时执行异步任务的操作new DownTask().execute(image_path) ;}}) ; //注意这个地方的分号容易遗忘}/* * 异步任务执行网络下载图片* */public class DownTask extends AsyncTaskString, Void, Bitmap {//上面的方法中第一个参数网络图片的路径第二个参数的包装类进度的刻度第三个参数任务执行的返回结果Override//在界面上显示进度条protected void onPreExecute() {dialog.show() ;};protected Bitmap doInBackground(String... params) { //三个点代表可变参数//使用网络链接类HttpClient类完成对网络数据的提取HttpClient httpClient new DefaultHttpClient() ;HttpGet httpget new HttpGet(params[0]) ;Bitmap bitmap null ;try {HttpResponse httpResponse httpClient.execute(httpget) ;if(httpResponse.getStatusLine().getStatusCode()200){HttpEntity httpEntity httpResponse.getEntity() ;byte[] data EntityUtils.toByteArray(httpEntity);bitmap BitmapFactory.decodeByteArray(data, 0, data.length);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return bitmap;}//主要是更新UIOverrideprotected void onPostExecute(Bitmap result) { super.onPostExecute(result);imageView.setImageBitmap(result) ;//更新UIdialog.dismiss() ; } }Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}} 运行后点击按钮显示结果如下 【实例二】从网络下载图片弹出能显示进度值的对话框 注既然要显示进度值所以此处的进度条风格要设置为水平。 1、添加网络授权同上 2、完整版代码如下 activity_main.xml的代码和【实例一】中的一样 MainActivity.java的代码 package com.example.smyh001downloadimage01;import java.io.ByteArrayOutputStream; import java.io.InputStream;import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient;import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView;public class MainActivity extends Activity {private ImageView imageView ;private Button button ; private ProgressDialog dialog ;//来自网络的图片private String image_path http://imgsrc.baidu.com/forum/pic/item/7c1ed21b0ef41bd51a5ac36451da81cb39db3d10.jpg ;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//添加弹出的对话框dialog new ProgressDialog(this) ;dialog.setTitle(提示) ;dialog.setMessage(正在下载图片请稍后···) ;//将进度条设置为水平风格让其能够显示具体的进度值dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) ;dialog.setCancelable(false) ; //用了这个方法之后直到图片下载完成进度条才会消失即使在这之前点击了屏幕imageView (ImageView)findViewById(R.id.imageView1) ;button (Button)findViewById(R.id.button1) ;button.setOnClickListener(new OnClickListener() {Overridepublic void onClick(View v) {//点击按钮时执行异步任务的操作new DownTask().execute(image_path) ;}}) ; //注意这个地方的分号容易遗忘} /* * 异步任务执行网络下载图片* */public class DownTask extends AsyncTaskString, Integer, byte[] {//上面的方法中第一个参数网络图片的路径第二个参数的包装类进度的刻度第三个参数任务执行的返回结果Override//在界面上显示进度条protected void onPreExecute() {dialog.show() ;};protected byte[] doInBackground(String... params) { //三个点代表可变参数//使用网络链接类HttpClient类完成对网络数据的提取即完成对图片的下载功能HttpClient httpClient new DefaultHttpClient() ;HttpGet httpget new HttpGet(params[0]) ;byte[] result null ;ByteArrayOutputStream outputStream new ByteArrayOutputStream() ;InputStream inputStream null ;try {HttpResponse httpResponse httpClient.execute(httpget) ;if(httpResponse.getStatusLine().getStatusCode()200){HttpEntity httpEntiry httpResponse.getEntity();inputStream httpEntiry.getContent();// 先要获得文件的总长度long file_length httpResponse.getEntity().getContentLength() ;int len 0 ;// 每次读取1024个字节byte[] data new byte[1024] ; // 每次读取后累加的长度int total_length 0 ; while ((len inputStream.read(data))!-1) {// 每读一次就将total_length累加起来total_lengthlen ;// 得到当前图片下载的进度int progress_value (int) ((total_length / (float)file_length)*100);// 时刻将当前进度更新给onProgressUpdate方法publishProgress(progress_value) ;outputStream.write(data, 0, len);}// 边读边写到ByteArrayOutputStream当中result outputStream.toByteArray();//bitmap BitmapFactory.decodeByteArray(result, 0, result.length) ;}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {httpClient.getConnectionManager().shutdown();}return result;}Overrideprotected void onProgressUpdate(Integer... values) {// TODO Auto-generated method stubsuper.onProgressUpdate(values);// 更新ProgressDialog的进度条dialog.setProgress(values[0]);}//主要是更新UI Overrideprotected void onPostExecute(byte[] result) { super.onPostExecute(result);// 将doInBackground方法返回的byte[]解码成要给BitmapBitmap bitmap BitmapFactory.decodeByteArray(result, 0, result.length) ;// 更新我们的ImageView控件imageView.setImageBitmap(bitmap) ;//更新UI// 使ProgressDialog框消失dialog.dismiss() ; } }Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}运行后显示结果如下 六、AsyncTask的重要知识点 明白了AsyncTask的工作原理后继续补充一下AsyncTask的一些其他知识点 1、Cancelling a Task 我们可以在任何时刻来取消异步任务的执行通过调用 cancel(boolean)方法调用完这个方法后系统会随后调用 isCancelled() 方法并且返回true。如果调用了这个方法那么在 doInBackgroud() 方法执行完之后就不会调用 onPostExecute() 方法了取而代之的是调用 onCancelled() 方法。如果有必要的话为了确保Task已经被取消了我们需要经常调用 isCancelled() 方法来判断。 2、在使用AsyncTask做异步任务的时候必须要遵循的原则 AsyncTask类必须在UI Thread当中加载在Android Jelly_Bean版本后这些都是自动完成的AsyncTask的对象必须在UI Thread当中实例化execute方法必须在UI Thread当中调用不要手动的去调用AsyncTask的四个方法这些都是由Android系统自动调用的AsyncTask任务只能被执行一次   【总结】 到此有关AsyncTask的总结就到此为止了本文主要讲解了Android中的多线程知识并且详细地讲解了 AsyncTask 异步任务的概念和实现机制并通过实例来了解 AsyncTask 的执行过程最后还补充了 AsyncTask 的一些重要知识点包括如何取消一个 AsyncTask 以及在使用 AsyncTask 时所必须遵循的规则。建议初学者包括我在理解这方面的问题时可以多参考官方的API文档。
http://www.pierceye.com/news/657198/

相关文章:

  • 网站开发证书网站推广应该怎么做?
  • 网站规划与网页设计案例网站建设php招聘
  • 网站内容页优化阿里巴巴做网站么
  • 网站百度收录秒收方法网页制作员厂家
  • 免费做网站怎么做网站619去加网 wordpress
  • 网站建设基本资料信息流优化师是干什么的
  • 网站开发项目经理招聘高级网站设计效果图
  • 上海建网站社交型网站开发
  • 西安建网站做自动化设备哪个网站
  • 深圳优化网站关键词wordpress如何拖移小工具
  • 优秀网站设计欣赏国内网站后期
  • 计算机应用技术php网站开发php网站进后台
  • asp网站安全小x导航正品
  • 陕西省建设监理协会网站成绩查询如何用网站做课件
  • 帝国网站怎么仿站个人做旅游网站的意义
  • 网站建设白沟做公众号策划的网站
  • 站长工具怎么用知名做网站哪家好
  • 做视频网站怎么备案企业内网
  • 建设网站南沙区建湖做网站找哪家好
  • 做网站应该会什么问题视频网站做app
  • 南阳做网站费用企业品牌维护
  • 分形科技做网站怎么样网站常用的js效果
  • 做企业展示网站网站建设与制作段考试题
  • 设计网站哪个好用网站建设策划方案t
  • 化妆培训学校网站建设徐州市工程建设交易平台
  • 杭州正规制作网站公司吗网站如何三合一
  • php网站开发说明手机网站建设的公司排名
  • 网站开发asp.net和sql数据库网页制作教程(第三版)书籍
  • wordpress搬站手机网站模板 html5
  • 免费设计网站网站开发及建设费用