asyntask配合线程池使用

asynctask遇到的问题

在android开发中许多同学都可能遇到asynctask的线程池爆掉的情况。

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
181    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
182    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
183    private static final int KEEP_ALIVE = 1;
192
193    private static final BlockingQueue<Runnable> sPoolWorkQueue =
194            new LinkedBlockingQueue<Runnable>(128);

上面的代码片中可以看出。

1、asynctask的核心线程数为CPU_COUNT+1。

2、线程等待队列的最大等待数为128。

asyntask对应的线城池ThreadPoolExecutor都是进程范围内共享的,其都是static的,所以是AsyncTask控制着进程范围内所有的子类实例。由于这个限制的存在,当使用默认线程池时,如果线程数超过线程池的最大容量,线程池就会爆掉。针对这种情况,可以尝试自定义线程池,配合asyntask使用。

asynctask自定义线程池

当我们在某个activity中开启多个线程池,用一个独立的线程池就显得比较方便,当然独立的线程池也需要一定的开销。独立线程池的会带来好处:

1、管理页面的线程,使其与activity联动:

     在Activity中,当页面的生命周期结束时,asynctask中的异步任务可能还没有完成,这导致了潜在的不稳定。一般情况下我们会做如下的处理:

if (activity == null || activity.isDestroy()) {//避免activity已经结束造成的空指针
	return;
}
在独立线程池中,我们通过终止线程池中的线程并销毁线程池的方式避免了上述情况的出现。同样的我们也可以实现一组形如onstart(),onpause()的方法来使线程池的生命周期和activity的生命周期联动。 由于独立线程池的存在,我们可以在页面不需要时彻底的销毁这个线程池并关闭所有的线程,这样可以有效的避免部分僵尸线程的存在。

2、自定义线程池的想关参数

     下面的内容可以看出系统默认线程池的策略。

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with Build.VERSION_CODES.DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with Build.VERSION_CODES.HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor,java.lang.Object[]) withTHREAD_POOL_EXECUTOR.

     默认线程存在这着线程池大小的限制,形如核心线程数限制为CPU_COUNT+1,这意味着同时并发执行的线程数为CPU_COUNT+1。自定义线程池均可设置这些参数,使用自定义的CorePoolSize为7的Executor(Executors.newFixedThreadPool(7)),这样可以同时并发执行7个异步线程,超过7个时则需等待。

asynctask自定义线程池实现

private static final int CORE_POOL_SIZE = 5;
	private static final int MAXIMUM_POOL_SIZE = 128;
	private static final int KEEP_ALIVE = 1;

	private   ThreadFactory sThreadFactory = new ThreadFactory() {
		private final AtomicInteger mCount = new AtomicInteger(1);
		public Thread newThread(Runnable r) {
			return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
		}
	};

	private   BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(10);

	/**
	 * An {@link Executor} that can be used to execute tasks in parallel.
	 */
	public  ThreadPoolExecutor threadPool= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

    public ThreadPoolExecutor getPool(){
    	return </span><span style="font-size: 14px;">threadpool</span><span style="font-family: Arial, Helvetica, sans-serif;">;</span><span style="font-size:14px;">
    }

形如上面的代码片,我们自定义了ThreadPoolExecutor,并配置了参数,代码中设置核心线程数为5,最大线程数128,同时自定义了等待队列。同时实现一个get方法方便使用线程池。
  getDetailTask.execute(threadContronler.getPool());
上面的代码asyntask将在自定义线程池中执行。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android的JavaMail库提供了一个简单而强大的方式来实现邮箱登录。下面是一个示例,展示如何使用JavaMail库在Android应用程序中实现邮箱登录: 首先,你需要在你的Android项目中导入JavaMail库。你可以通过在build.gradle文件中添加以下代码来完成这一步骤: implementation 'javax.mail:javax.mail-api:1.6.2' implementation 'com.sun.mail:android-mail:1.6.2' implementation 'com.sun.mail:android-activation:1.6.2' 然后,你需要创建一个AsynTask类来处理与邮箱登录相关的网络请求。在这个AsynTask类的doInBackground方法中,你可以使用JavaMail库的API来连接到你的邮箱,并通过邮箱提供的验证机制进行登录。以下是一个基本的示例代码: private class EmailLoginTask extends AsyncTask<Void, Void, Boolean> { private String email; private String password; public EmailLoginTask(String email, String password) { this.email = email; this.password = password; } @Override protected Boolean doInBackground(Void... params) { try { Properties properties = new Properties(); properties.put("mail.store.protocol", "imaps"); // 使用IMAP协议连接到邮箱服务器 properties.put("mail.imaps.host", "imap.mail.com"); // 邮箱服务器地址 properties.put("mail.imaps.port", "993"); // 邮箱服务器端口号 Session session = Session.getDefaultInstance(properties); Store store = session.getStore("imaps"); store.connect(email, password); // 使用邮箱和密码进行登录 return true; // 登录成功 } catch (Exception e) { e.printStackTrace(); return false; // 登录失败 } } @Override protected void onPostExecute(final Boolean success) { if (success) { // 登录成功,执行相关逻辑操作 } else { // 登录失败,显示错误信息 } } } 最后,在你的Android活动或碎片中,你可以实例化这个AsynTask类,并调用execute方法来执行邮箱登录任务。例如: String email = "yourEmail@mail.com"; String password = "yourPassword"; EmailLoginTask loginTask = new EmailLoginTask(email, password); loginTask.execute(); 需要注意的是,这只是一个简单的示例。在实际开发中,你可能需要进一步处理验证失败、网络连接错误等异常情况,并根据实际需求在登录成功后执行相应的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值