本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask,我们一般是 继承AsyncTask,然后在类中实现异步操作,然后将异步执行的进度,反馈给UI主线程~
http://blog.csdn.net/xiangyong_1521/article/details/50516055
一.相关概念
1)什么是多线程:
2)同步与异步的概念:
3) Android为很么要引入异步任务
因为Android程序刚启动时,会同时启动一个对应的主线程(Main Thread),这个主线程主要负责处理 与UI相关的事件!有时我们也把他称作UI线程!而在Android App时我们必须遵守这个单线程模型的规则: Android UI操作并不是线程安全的并且这些操作都需要在UI线程中执行! 假如我们在非UI线程中,比如在主线程中new Thread()另外开辟一个线程,然后直接在里面修改UI控件的值; 此时会抛出下述异常:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views
另外,还有一点,如果我们把耗时的操作都放在UI线程中的话,如果UI线程超过5s没有响应用于请求,那么 这个时候会引发ANR(Application Not Responding)异常,就是应用无响应~ 最后还有一点就是:Android 4.0后禁止在UI线程中执行网络操作~不然会报:
android.os.NetworkOnMainThreadException
以上的种种原因都说明了Android引入异步任务的意义,当然实现异步也不可以不用到我们本节讲解 的AsyncTask,我们可以自己开辟一个线程,完成相关操作后,通过下述两种方法进行UI更新:
1)为什么要用AsyncTask?
我们可以用上述两种方法来完成我们的异步操作,加入要我们写的异步操作比较多,或者较为繁琐, 难道我们new Thread()然后用上述方法通知UI更新么?程序员都是比较喜欢偷懒的,既然官方给我们提供了AsyncTask这个封装好的轻量级异步类,为什么不用呢?我们通过几十行的代码就可以完成我们的异步操作,而且进度可控;相比起Handler,AsyncTask显得更加简单,快捷~当然,这只适合简单的异步操作,另外,实际异步用的最多的地方就是网络操作,图片加载,数据传输等,AsyncTask暂时可以满足初学者的需求,谢谢小应用,但是到了公司真正做项目以后,我们更多的使用第三发的框架,比如Volley,OkHttp,android-async-http,XUtils等很多,后面进阶教程我们会选1-2个框架进行学习,当然你可以自己找资料学习学习,但是掌握AsyncTask还是很有必要的!
2)AsyncTask的基本结构:
AsyncTask是一个抽象类,一般我们都会定义一个类继承AsyncTask然后重写相关方法~ 官方API:AsyncTask
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="播放" /> </LinearLayout>
public class MyAsyncTask extends AsyncTask<Integer,Integer,String>{ private TextView txt; private SeekBar seekBar; public MyAsyncTask(TextView txt, SeekBar seekBar) { super(); this.txt=txt; this.seekBar=seekBar; } //该方法不运行在UI线程中,主要用于异步操作,通过调用publishProgress()方法 //触发onProgressUpdate对UI进行操作 @Override protected String doInBackground(Integer... params) { int i=0; try { DelayOperator dop=new DelayOperator(); for(i=10;i<=1000;i+=10) { dop.delay(); publishProgress(i); } } catch (Exception e) { } return i+params[0].intValue()+""; } //该方法运行在UI线程中,可对UI控件进行设置 @Override protected void onPreExecute() { try { txt.setText("正在播放"); } catch (Exception e) { e.printStackTrace(); } } @Override protected void onProgressUpdate(Integer... values) { int value=values[0]; seekBar.setProgress(value); } }
package com.example.text_ansynctask; public class DelayOperator { public void delay(){ try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }
public class MainActivity extends Activity { private Button button; private TextView textView; private SeekBar seekBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button=(Button) findViewById(R.id.button1); textView=(TextView) findViewById(R.id.textView1); seekBar=(SeekBar) findViewById(R.id.seekBar1); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyAsyncTask myTask=new MyAsyncTask(textView,seekBar); Toast.makeText(MainActivity.this, "开始播放", 1).show(); myTask.execute(1000); } }); } }