day4.19总结_异步任务和线程池

一、异步任务对象(AsyncTask)

1)概述

1AsyncTask 是一个工具类,它封装了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)提高系统的整体执行性能。

3Java中线程池的创建及应用

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)构建异步任务对象

1new DownTask().execute(pos)   每次点击会构建一个任务,然后在那个默认的工作线程中执行

2downTask(pos)    适合多个任务顺序执行的场合

3new 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());

}

  });

}

}

}

 

5scheduled

例子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 ()

基本同上!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值