目前常用的线程有:
- class MyAsyncTask extends AsyncTask<URL,Integer,Long>{
- /**
- * 执行异步任务
- * @param urls
- * @return
- */
- @Override
- protected Long doInBackground(URL... urls) {
- int count=100;
- long totalSize=0;
- for (int i=0;i<count;i++){
- totalSize+=10;
- publishProgress(i*100/count); //调用onProgressUpdate
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (isCancelled()){
- break;
- }
- }
- return totalSize;
- }
-
- /**
- * 执行之前调用
- */
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
-
- /**
- * 完成时调用
- * @param aLong
- */
- @Override
- protected void onPostExecute(Long aLong) {
- super.onPostExecute(aLong);
- tv_display.setText("Download"+aLong+"bytes");
- }
-
- /**
- * 后台进度发生改变时调用
- * @param values
- */
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- tv_display.setText("进度"+values[0]);
- }
- }
new MyAsyncTask().execute();
- @Override
- public void run() {
- mTid = Process.myTid();
- Looper.prepare();
- synchronized (this) {
- mLooper = Looper.myLooper();
- notifyAll();
- }
- Process.setThreadPriority(mPriority);
- onLooperPrepared();
- Looper.loop();
- mTid = -1;
- }
可以看到其内部的run方法,直接新建了Looper。这样就能在非UI线程中,创建Handler了。
这个方法一般配合IntentService使用,
- public class MyIntentService extends IntentService {
-
- private static final String TAG = "MyIntentService";
-
- public MyIntentService() {
- this(null);
- }
-
- /**
- * Creates an IntentService. Invoked by your subclass's constructor.
- *
- * @param name Used to name the worker thread, important only for debugging.
- */
- public MyIntentService(String name) {
- super(name);
- }
-
- @Override
- protected void onHandleIntent(@Nullable Intent intent) {
- Log.d(TAG, "onHandleIntent: "+intent.getStringExtra("action"));
- SystemClock.sleep(3000);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- Log.d(TAG, "onDestroy: MyIntentService");
- }
- }
- Intent intent=new Intent(ThreadTestActivity.this,MyIntentService.class);
- for (int i=0;i<5;i++){
-
- intent.putExtra("action","action"+i);
- startService(intent);
- }
注意:虽然IntentService很像thread ,但是本质仍然是service,需要在androidManifest中进行注册。
- @Override
- public void onCreate() {
- // TODO: It would be nice to have an option to hold a partial wakelock
- // during processing, and to have a static startService(Context, Intent)
- // method that would launch the service & hand off a wakelock.
-
- super.onCreate();
- HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
- thread.start();
-
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- }
可以看出IntentService在创建的时候,就创建了HandlerThread,然后通过他的Looper创建了Handler。
而在IntentService每次被startServcie的时候,都会调用onStartCommand,然后startCommand又会去调用onstart方法,所以我们来看下onstart方法。
- @Override
- public void onStart(@Nullable Intent intent, int startId) {
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- msg.obj = intent;
- mServiceHandler.sendMessage(msg);
- }
可以看出,在onstart方法中,intentService 将startSevice的intent和startId。放入了handler中。既让放入了handler中,那么我们就需要去看下handlerMessage方法
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- onHandleIntent((Intent)msg.obj);
- stopSelf(msg.arg1);
- }
- }
这个就很简单了,在handler中如果收到消息,则调用抽象方法onHandlerIntent 去处理,而onHandlerIntent ,就是我们需要实现的方法。也就实现了,在非UI线程执行某个操作。
而最后的stopSerlf,传入的是startId。这个方法会对比现在传入的startId和IntentrService收到的最后第一个startId是不是一样的。也就是当前处理的消息是不是最后一条消息,如果是最后一条消息,则停止该service。
注意: 由于IntentService内部是由handler实现的,所以也具有Handler的特点。也就是串行执行的,一个方法执行完成以后,才会执行下一个方法。
android中常用的线程池
构造方法
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue,
- ThreadFactory threadFactory) {
- this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- threadFactory, defaultHandler);
- }
corePoolSize
核心线程的数量,默认一直存活。可以通过allowCoreThreadTimeOut和keepAliveTime配置是否闲置超时关闭和超时的时间
maximumPoolSize
线程池最大的线程数,超出将阻塞
keepAliveTime
配置非核心线程超时关闭的时间。通过allowCoreThreadTimeOut也可以配置核心线程超时关闭的时间
unit
超时的单位,枚举值。
workQueue
存储任务的队列
threadFactory
线程工厂,提供创建新进程的功能
核心代码
- public static ExecutorService newFixedThreadPool(int nThreads) {
- return new ThreadPoolExecutor(nThreads, nThreads,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>());
- }
从上面代码可以看出,是创建了一个具有以下特点的线程池
该线程使用场景:适合数量较少耗时较长的任务
核心代码
- public static ExecutorService newCachedThreadPool() {
- return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
- 60L, TimeUnit.SECONDS,
- new SynchronousQueue<Runnable>());
- }
从上面代码可以看出,该方法创建了一个具有以下特点的线程池
该线程使用场景:适合数量大耗时较少的任务
核心代码
- public ScheduledThreadPoolExecutor(int corePoolSize) {
- super(corePoolSize, Integer.MAX_VALUE,
- DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
- new DelayedWorkQueue());
- }
该线程池的特点
该线程使用场景:执行定时和具有周期性的任务
核心代码
- public static ExecutorService newSingleThreadExecutor() {
- return new FinalizableDelegatedExecutorService
- (new ThreadPoolExecutor(1, 1,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>()));
- }
该线程池的特点
该线程使用场景:可以统一所有外界任务到一个线程中,任务之间不需要处理线程同步的问题。