Android线程总结一

自己写了很多博客了吧,今天在写项目的时候,需要把之前使用的一些AsyncTask的内容切换成线程池,结果发现,我竟然没有写过这样的总结,真的是太大意了,所以我现在就把之前使用过的关于线程的问题,不管是AsyncTask也好,还是线程池也好,或者说是Handler,做一个全面的总结,为自己以后复习留下个记录

AsyncTask

关于定义

AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

这个是官网给出的解释,意思就是说(自己的翻译,凑合看吧)
AsyncTask能够适当和简单的使用UI线程。这个类允许你执行后台操作和公布结果到UI线程,而不需要操作线程或者handler

这里不是关键,关键的实在下面

AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler} and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as {@link Executor}, {@link ThreadPoolExecutor} and {@link FutureTask}.

这句话比较长,具体的意思
AsyncTask是一个帮助类,可以让我们去执行一些比较小,耗时比较短的线程异步操作,但是如果你的耗时操作比较长,建议你不要使用这样的方式,还是使用线程池比较好

具体的关于AsyncTask的操作,请查看另外一个博客[android2017年面试]

线程池框架、Executor、ThreadPoolExecutor

Android中的线程池框架,跟Java的是一样的,所以,我们这里直接给大家解释
Android中的线程池框架分为3个部分
1. 任务:包括被执行任务需要实现的接口类:Runnable 或 Callable
2. 任务的执行器:包括任务执行机制的核心接口类Executor,以及继承自Executor的EexcutorService接口
3. 执行器的创建者,工厂类Executors

Executor 和 ExecutorService

Executor只是一个接口,它是Java/Android线程池框架的基础,它将任务的提交与任务的执行分离开来。
ExecutorService继承自Executor,有两个关键类实现了ExecutorService接口:ThreadPoolExecutor和ScheduledThreadPoolExecutor。
- ThreadPoolExecutor 是线程池的核心实现类,用来执行被提交的任务
- ScheduledThreadPoolExecutor 也是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。它比Timer更灵活,功能更强大
继承关系

Executors工厂类

Executors是一个工厂类,它不继承任何其它类,它通过ThreadPoolExecutor、ScheduledThreadPoolExecutor创建出四种不同的线程池,分别为
1. newCachedThreadPool 创建一个可缓存线程池,线程池的最大长度无限制,但如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
Executors.java

public static ExecutorService newCachedThreadPool() {  
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
                                     60L, TimeUnit.SECONDS,  
                                     new SynchronousQueue<Runnable>());  
}  

使用实例

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
for (int i = 0; i < 10; i++) {  
    final int index = i;  
    try {  
        Thread.sleep(index * 1000);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  

    cachedThreadPool.execute(new Runnable() {  

        @Override  
        public void run() {  
            System.out.println(index);  
        }  
    });  
} 
  1. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
    Executors.java
public static ExecutorService newFixedThreadPool(int nThreads) {  
    return new ThreadPoolExecutor(nThreads, nThreads,  
                                  0L, TimeUnit.MILLISECONDS,  
                                  new LinkedBlockingQueue<Runnable>());  
} 

使用实例

for (int i = 0; i < 10; i++) {  
    final int index = i;  
    fixedThreadPool.execute(new Runnable() {  

        @Override  
        public void run() {  
            try {  
                System.out.println(index);  
                Thread.sleep(2000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    });  
} 
  1. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行
    Executors.java
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {  
    return new ScheduledThreadPoolExecutor(corePoolSize);  
} 

实用实例:延时三秒执行

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
scheduledThreadPool.schedule(new Runnable() {  

    @Override  
    public void run() {  
        System.out.println("delay 3 seconds");  
    }  
}, 3, TimeUnit.SECONDS); 

延时一秒每三秒执行一次

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {  

    @Override  
    public void run() {  
        System.out.println("delay 1 seconds, and excute every 3 seconds");  
    }  
}, 1, 3, TimeUnit.SECONDS);  
  1. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    Executors.java
public static ExecutorService newSingleThreadExecutor() {  
    return new FinalizableDelegatedExecutorService  
        (new ThreadPoolExecutor(1, 1,  
                                0L, TimeUnit.MILLISECONDS,  
                                new LinkedBlockingQueue<Runnable>()));  
}

实用实例

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();  
for (int i = 0; i < 10; i++) {  
    final int index = i;  
    singleThreadExecutor.execute(new Runnable() {  

        @Override  
        public void run() {  
            try {  
                System.out.println(index);  
                Thread.sleep(2000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    });  
}  

写一个例子:

/**
 * Created: niupule
 * Date: 2018/5/21  下午2:37
 * E-mail:niupuyue@aliyun.com
 * des:
 *  线程池管理类
 */

public class ThreadPoolManager {

    //单例模式
    private static ThreadPoolManager manager = new ThreadPoolManager();

    public static ThreadPoolManager getInstance() {
        return manager;
    }

    //核心线程池的数量,能够同时执行线程的数量
    private int corePoolSize;
    //最大线程池数量
    private int maxPoolSize;
    //存活时间
    private long keepAliveTime = 1;
    //时间计量单位
    private TimeUnit unit = TimeUnit.HOURS;
    //线程池对象
    private ThreadPoolExecutor executor;

    //构造方法
    private ThreadPoolManager() {
        //给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)
        corePoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
        maxPoolSize = corePoolSize;
        executor = new ThreadPoolExecutor(
                corePoolSize,//当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务
                maxPoolSize,//5,先corePoolSize,然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
                keepAliveTime,//表示的是maximumPoolSize当中等待任务的存活时间
                unit,
                new LinkedBlockingQueue<Runnable>(),//缓冲队列,用于存放等待任务,Linked的先进先出
                Executors.defaultThreadFactory(),//创建线程的工厂
                new ThreadPoolExecutor.AbortPolicy()//用来对超出maximumPoolSize的任务的处理策略
        );
    }

    //执行任务
    public void execute(Runnable runnable){
        if(runnable == null)
            return;
        executor.execute(runnable);
    }

    //从线程池中移除任务
    public void remove(Runnable runnable){
        if (runnable == null)
            return;
        executor.remove(runnable);
    }
}

这里还需要添加一个线程

/**
 * Created: niupule
 * Date: 2018/5/21  下午2:50
 * E-mail:niupuyue@aliyun.com
 * des:
 * 子线程,浏览本地文件
 */

public class FilterFiles implements Runnable {

    //系统文件根目录
    private File rootAll = new File(CommonUtil.getExternalStorageDirectory());
    //需要查找的文件类型
    private String[] docType = {};
    //需要返回给的数据
    private List<File> files ;
    //handler对象
    private Handler handler;

    //构造方法
    public FilterFiles(String[] docType,Handler handler){
        files = new ArrayList<File>();
        this.docType = docType;
        this.handler = handler;
    }

    @Override
    public void run() {
        //耗时操作执行循环遍历
        FindAllTypeDocment(rootAll);
        //执行完成之后,返回files数据
        //获取Message对象
        Message msg = Message.obtain();
        //设置返回的flag
        msg.what = 100;
        msg.obj = files;
        handler.sendMessage(msg);
    }

    //递归遍历数据
    public void FindAllTypeDocment(File root){
        if(root.isDirectory()) {
            File[] fileArray = root.listFiles();
            for (int i = 0; i < fileArray.length; i++) {
                File f = fileArray[i];
                if (f.isDirectory()) {
                    FindAllTypeDocment(f);
                } else if (f.getName().endsWith(docType[0]) || f.getName().endsWith(docType[1])) {
                    files.add(f);
                }
            }
        }
    }

}

在使用的时候,需要创建一个新的handler对象,并且使用的时候新建线程对象

public class LocalDocFragment extends Fragment implements LocalAllFileItemCallback{
    //视图的recyclerview
    private RecyclerView recyclerView;
    //视图适配器
    private LocalAllFileAdapter adapter;
    //需要显示的文件列表集合
    private List<File> files = new ArrayList<File>();
    //无数据显示样式
    private LinearLayout local_doc_nodata;
    //sqlite数据库操作
    private RecentFileDao dao = new RecentFileDao();
    //加载进度
    private LinearLayout local_doc_loading;
    private ProgressBar progressBar;
    //数据加载的handler
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 100:
                    files = (List<File>) msg.obj;
                    if (files != null && files.size() > 0) {
                        recyclerView.setAdapter(adapter = new LocalAllFileAdapter(getContext(), files, LocalDocFragment.this));
                        recyclerView.addItemDecoration(new RecycleViewItemDecoration());
                        local_doc_nodata.setVisibility(View.GONE);
                    } else {
                        local_doc_nodata.setVisibility(View.VISIBLE);
                    }
                    //关闭进度条
                    local_doc_loading.setVisibility(View.GONE);
                    progressBar.setVisibility(View.GONE);
                    break;
                case 101:
                    break;
            }
        }
    };

    public static LocalDocFragment newIstance() {
        LocalDocFragment localDocFragment = new LocalDocFragment();
        return localDocFragment;
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_local_doc, null);
        recyclerView = view.findViewById(R.id.local_doc_recycleview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        local_doc_nodata = view.findViewById(R.id.local_doc_nodata);
        local_doc_loading = view.findViewById(R.id.local_doc_loading);
        progressBar = view.findViewById(R.id.local_doc_progressbar);
        //让加载页面显示
        local_doc_loading.setVisibility(View.VISIBLE);
        progressBar.setVisibility(View.VISIBLE);
        //从线程池中拿到数据
        ThreadPoolManager.getInstance().execute(new FilterFiles(new String[]{".doc",".docx"},handler));
        return view;
    }

    /**
     * 点击其中的选项之后需要执行的操作
     */
    @Override
    public void onItemClick(View view, int position) {
        if (files != null && files.size() > position) {
            File file = files.get(position);
            IFile iFile = new LocalFile(file.toURI());
            FileUtils.open(iFile, getActivity());
            File file_recent = files.get(position);
            dao.addRecentFile(file_recent.getName(), file_recent.getAbsolutePath(), FileUtils.generateTime(file_recent), FileUtils.generateSize(file_recent));
            EventBus.getDefault().post(new Msg_Sql());
        }
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值