线程及异步操作
大体上阐述了异步处理的重要性,以及什么时候应该用异步处理等等巴拉巴拉......
重点:
1:
AsyncTask类的介绍及例子......
通过继承AsyncTask类并实现其定义的事件方法,管理后台操作。
很方便的是AsyncTask类已经为异步操作创建好了一个简单的接口,我们只需实现这个接口就可以很快捷的实现异步操作。
并且在最新的几个SDK中,它能够通过若干个物理内核和一个内部线程池来同时管理多个任务。
包括:
onPreExecute()方法在后台操作开始前运行在UI线程上
doInBackground()方法运行在后台并处理后台操作
从该方法中调用publishProgress()方法能够周期性的通知UI线程有关后台操作的进度
当其( doInBackground()方法 )调用publishProgress()方法时
onProgressUpdate()方法就会在UI线程中运行,通过不同的参数来传递不同的信息
一旦后台操作完成,就会自动在UI线程中调用onPostExrcute()方法,AsyncTask类能够以后台的方式处理操作,不会阻塞UI线程。
启动方法有2种:
1.实例化所创建的AsyncTask子类,调用execute()方法,启动异步操作。
2.实例化所创建的AsyncTask子类,调用executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, Integer... )方法,启动异步操作。
区别:API L11+的设备中,前者( execute() ) 任务可以”平行“的被执行,在多核处理器设备上,该方法能有效地提高任务的完成速度,并隐性的提高应用程序的效率和流畅性。后者( executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, Integer... ) )则保证了同时执行若干个任务,每个任务相互独立。
注:如果不想同时执行多个任务,可以调用executeOnExecutor( AsyncTask.SERIAL_EXECUTOR )方法,但是只有再API L14+中才能确认是线性的。
实例:
1 package com.example.asynctask; 2 3 import android.os.AsyncTask; 4 import android.os.Bundle; 5 import android.os.SystemClock; 6 import android.app.Activity; 7 import android.widget.TextView; 8 9 public class SimpleAsyncTask extends Activity { 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 16 CountingTask tsk = new CountingTask(); 17 tsk.execute(); 18 19 } 20 21 private class CountingTask extends AsyncTask<Void, Integer, Integer> { 22 23 CountingTask() { 24 } 25 26 @Override 27 protected Integer doInBackground(Void... unused) { 28 29 int i = 0; 30 while (i < 100) { 31 32 SystemClock.sleep(100); 33 i++; 34 35 if (i % 5 == 0) { 36 37 // 每5%进度更新一次UI 38 publishProgress(i); 39 } 40 } 41 42 return i; 43 } 44 45 protected void onProgressUpdate(Integer... progress) { 46 47 TextView tv = (TextView) findViewById(R.id.text); 48 tv.setText(progress[0] + " % Complete! "); 49 } 50 51 protected void onPostExecute(Integer result) { 52 53 TextView tv = (TextView) findViewById(R.id.text); 54 tv.setText("Count Complete ! Count to " + result.toString()); 55 } 56 } 57 }
1 package com.example.asynctask; 2 3 import android.app.Activity; 4 import android.os.AsyncTask; 5 import android.os.Bundle; 6 import android.os.SystemClock; 7 import android.widget.TextView; 8 9 public class SimpleMultiCoreAsyncTask extends Activity { 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_simple_multi_core_async_task); 15 16 CountingTask tsk = new CountingTask(); 17 tsk.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, R.id.tv_AsyncTask_1 ); 18 19 startParallelTask( R.id.tv_AsyncTask_2 ); 20 startParallelTask( R.id.tv_AsyncTask_3 ); 21 startParallelTask( R.id.tv_AsyncTask_4 ); 22 startParallelTask( R.id.tv_AsyncTask_5 ); 23 startParallelTask( R.id.tv_AsyncTask_6 ); 24 25 //注意,貌似只能第一时间同时启动前5个,完成后才会启动第6个...... 26 } 27 28 private void startParallelTask( int _id ) { 29 30 CountingTask tsk = new CountingTask(); 31 tsk.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, _id ); 32 } 33 34 private class CountingTask extends AsyncTask<Integer, Integer, Integer> { 35 36 private int _counterID; 37 38 CountingTask() { 39 } 40 41 @Override 42 protected Integer doInBackground(Integer... _id) { 43 44 _counterID = _id[ 0 ]; 45 int i = 0; 46 47 while (i < 100) { 48 49 SystemClock.sleep(100); 50 i++; 51 52 if (i % 5 == 0) { 53 54 // 每5%进度更新一次UI 55 publishProgress(i); 56 } 57 } 58 59 return i; 60 } 61 62 protected void onProgressUpdate(Integer... progress) { 63 64 TextView tv = (TextView) findViewById( _counterID ); 65 tv.setText(progress[0] + " % Complete! "); 66 } 67 68 protected void onPostExecute(Integer result) { 69 70 TextView tv = (TextView) findViewById( _counterID ); 71 tv.setText("Count Complete ! Count to " + result.toString()); 72 } 73 } 74 }
------------------------------------------------我是分割线--------------------------------------------------------------
2:Thread类
比起上面的( AsyncTask ) ,其( Thread )类导入已有的代码更为简便直接
对于一个拥有独立线程的Activity类能够管理线程的生命周期,一般就会包括一个Handler类型的变量,Thread类被实例化启动时,Handler的post()方法就会被用于与主UI线程的通信,当然也可以使用Activity类中的runOnThread()方法或是View类中的post()和postDelayed()方法来与主UI线程通信。
实例:
1 package com.example.asynctask; 2 3 import android.os.Bundle; 4 import android.os.SystemClock; 5 import android.app.Activity; 6 import android.view.Menu; 7 import android.widget.TextView; 8 9 public class SimpleThread extends Activity { 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_simple_thread); 15 16 final TextView tv_thread = ( TextView ) findViewById( R.id.tv_thread ); 17 18 new Thread( new Runnable() { 19 20 @Override 21 public void run() { 22 23 int i = 0; 24 25 while ( i < 100 ) { 26 27 SystemClock.sleep( 250 ); 28 i++; 29 30 final int curCount = i; 31 32 if( curCount % 5 == 0 ) { 33 34 tv_thread.post( new Runnable() { 35 36 @Override 37 public void run() { 38 39 tv_thread.setText( curCount + " % Complete! " ); 40 } 41 }); 42 } 43 } 44 45 tv_thread.post( new Runnable() { 46 47 @Override 48 public void run() { 49 50 tv_thread.setText( "Count Complete!" ); 51 } 52 }); 53 } 54 }).start(); 55 } 56 }