一、异步任务对象(AsyncTask)
(1)概述
(1)AsyncTask 是一个工具类,它封装了android中消息模型的的应用过程,用于简化消息传递及处理的方式,此类是一个抽象类,它内部定义的方法有的定义主线程,有的运行在工作线程,我们在使用此类时,通常要根据需要重写其中方法。
(2)当我们在执行异步任务时,要构建异步任务对象,然后调用对象的executeXXX方法执行任务。
(2)常用方法:
(1)doInBackground 运行在工作线程
(2)onPreExecute 运行在主线程,在doInBackground之前执行
(3)onProgressUpdate 用于执行进度更新操作,它工作在主线程
(4)onPostExecute 运行在主线程,在doInBackground方法之后执行
(5)publishProgress 发布进度
例子1:更新下载进度条
public class MainActivity extends Activity { private ProgressBar pBar; private TextView tv01; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pBar=(ProgressBar) findViewById(R.id.progressBar1); tv01=(TextView) findViewById(R.id.textView01); imageView=(ImageView) findViewById(R.id.imageView1); }
class Task01 extends AsyncTask<File,Integer,Bitmap>{ /**此方法运行在主线程,在doInBackground之前执行*/-------初始化 @Override protected void onPreExecute() { pBar.setVisibility(View.VISIBLE); tv01.setVisibility(View.VISIBLE); } /**此方法运行在工作线程*/ ------------读取数据 @Override protected Bitmap doInBackground(File... params) {这个数组 pBar.setMax((int)params[0].length()); //1.构建流对象 InputStream in=null; byte buf[]=new byte[16]; int len=-1; ByteArrayOutputStream out=new ByteArrayOutputStream(); byte array[]=null; int count=0; try{ in=new FileInputStream(params[0]); //2.读取数据 while((len=in.read(buf))!=-1){ out.write(buf, 0, len); count+=len; pBar.setProgress(count); //发布进度 publishProgress(count,(int)params[0].length()); } array=out.toByteArray(); }catch(Exception e){ e.printStackTrace(); }finally{ //3.释放资源 if(in!=null)try{in.close();in=null;}catch(Exception e){} if(out!=null)try{out.close();}catch(Exception e){} } //将数组中的内容转换为bitMap对象 return BitmapFactory.decodeByteArray(array,0, array.length); } /**此方法用于执行进度更新操作,它工作在主线程*/-----------更新进度 @Override protected void onProgressUpdate(Integer... values) { tv01.setText(String.valueOf(values[0])+"/"+String.valueOf(values[1])); } /**此方法运行在主线程,在doInBackground方法之后执行*/ @Override protected void onPostExecute(Bitmap result) {-------------执行完最后的动作 pBar.setVisibility(View.GONE); tv01.setVisibility(View.GONE); imageView.setImageBitmap(result); } } public void onClick01(View v){ //构建异步任务对象 Task01 task=new Task01(); //执行异步任务对象 sdcard下的目录 File sdcard=Environment.getExternalStorageDirectory(); 一开始忘了 File file=new File(sdcard,"lyfa.jpg"); task.execute(file); } } |
二、线程池的应用
(1)何为线程池?
1)内存中的一块区域
2)允许存储若干个可重用线程对象。
(2)使用线程池的目的
1)减少线程对象的创建次数,提高线程对象的利用率。
2)提高系统的整体执行性能。
(3)Java中线程池的创建及应用
1)Executors (工具类)
2)Executor(线程池对象)
.构建一个线程池对象
ExecutorService es=Executors.newSingleThreadExecutor();
ExecutorService es=Executors.newFixedThreadPool(2);//有上限的线程池对象
ExecutorService es=Executors.newCachedThreadPool();//线程数量没有上限
a)ExecutorService(线程池接口类型,继承Executor)
a.1)execute(....)
a.2)submit(....)
b)ThreadPoolExecutor(具体线程池对象)
c)ScheduledExecutorService(继承ExecutorService)
例子2:在主线程中获得结果
public class ThreadPoolDemo02 { public static void main(String[] args)throws Exception { ExecutorService es=Executors.newSingleThreadExecutor(); //启动线程池中的线程求某个整数的阶乘 //并在主线程中获得结果。 Future<?> f=es.submit(new Callable<Integer>() {//代表一个任务对象 @Override public Integer call() throws Exception { //try{Thread.sleep(5000);}catch(Exception e){} return get(7); } }); //get方法为一个阻塞式方法,需要等待任务的执行结果 System.out.println(f.get());//此方法需等任务执行结束 es.shutdown(); } public static int get(int n){ int result=1; for(int i=1;i<=n;i++){ result*=i; } return result; } } |
(4)构建异步任务对象
(1)new DownTask().execute(pos) 每次点击会构建一个任务,然后在那个默认的工作线程中执行
(2)downTask(pos) 适合多个任务顺序执行的场合
(3)new DownTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pos);
适合多个任务并发执行的场合
例子3:同时下载
public class MainActivity extends ListActivity { private List<String> dbList=new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); dbList.add("支付宝"); dbList.add("微信"); dbList.add("QQ"); setListAdapter(new ArrayAdapter<String>(this,R.layout.list_item_2,R.id.textView1,dbList){ @Override public View getView(int position, View convertView, ViewGroup parent) { View v=super.getView(position, convertView, parent); final ImageButton btn=(ImageButton)v.findViewById(R.id.imageView1); btn.setTag(position); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int pos=(Integer)btn.getTag(); //每次点击会构建一个任务,然后在那个默认的工作线程中执行 //new DownTask().execute(pos); //downTask(pos);//适合多个任务顺序执行的场合 //如下方法适合多个任务并发执行的场合 new DownTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pos); } }); return v; } }); } class DownTask extends AsyncTask<Integer, Void, Void>{ @Override protected Void doInBackground(Integer... params) { Log.i("TAG", "下载第"+params[0]+"软件"); try{Thread.sleep(10000);}catch(Exception e){} return null; } } public void downTask(final int position){ AsyncTask.execute(new Runnable() { @Override public void run() { Log.i("TAG", "下载第"+position+"软件"); try{Thread.sleep(10000);}catch(Exception e){} } }); } } |
例子4:自己new的线程池
public class ThreadPoolDemo03 { private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { System.out.println("newThread"); return new Thread(r, "Thread #" + mCount.getAndIncrement()); } };
public static void main(String[] args) { final BlockingQueue<Runnable> workQueue= //new ArrayBlockingQueue<>(10); new LinkedBlockingQueue<>(10); //new LinkedBlockingQueue<>(); Executor pool=new ThreadPoolExecutor( 5,//corePoolSize 20,//maximumPoolSize 1,//keepAliveTime 参数参考 TimeUnit.SECONDS, //TimeUnit workQueue, //BlockingQueue sThreadFactory);//可以参考Executors.defaultThreadFactory() for(int i=0;i<100;i++){ pool.execute(new Runnable() { @Override public void run() { System.out.println("workQueue.size()="+workQueue.size()); System.out.println(Thread.currentThread().getName()); } }); } } } |
(5)scheduled
例子5:延迟执行schedule(new Runnable())
public class ThreadPoolDemo04 { public static void main(String[] args) { ScheduledExecutorService es=Executors.newScheduledThreadPool(2); 创建两个线程 es.schedule(new Runnable() { 注意方法 @Override public void run() { String tname=Thread.currentThread().getName(); System.out.println(tname+"-->task01"); } }, 3, TimeUnit.SECONDS);//延迟3秒以后执行
es.schedule(new Callable<Integer>() { @Override public Integer call() throws Exception { String tname=Thread.currentThread().getName(); System.out.println(tname+"-->task02"); return -1; } }, 8, TimeUnit.SECONDS);//延迟8秒以后执行 es.shutdown(); } } |
例子6:按一定的间隔执行任务scheduleAtFixedRate (new Runnable())
public class ThreadPoolDemo05 { public static void main(String[] args) { ScheduledExecutorService es=Executors.newScheduledThreadPool(10); //重复性性的执行任务 es.scheduleAtFixedRate(new Runnable() { @Override public void run() { String tname=Thread.currentThread().getName(); System.out.println(tname+"-->task01"); } },//command任务Runnable 1,//initialDelay初始延迟 1,//period 时间间隔(两次任务启动的间隔时间,不管上一次任务是否已经结束) TimeUnit.SECONDS);//unit 时间单位 //重复性的执行任务 es.scheduleWithFixedDelay(new Runnable() { @Override public void run() { System.out.println("task02"); } },//command 1,//initialDelay 1,//delay(任务执行结束以后再延迟delay时间开启下一次任务) TimeUnit.SECONDS);//unit } } |
例子7:按一定的间隔(任务执行时间+delay)执行任务scheduleWithFixedDelay ()
基本同上! |