`
学会做人
  • 浏览: 120944 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

自定义AsyncTask

阅读更多
package com.example.gradlebuildsimple;

import java.io.InterruptedIOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;


/**
 *  自定义AsyncTask:
 *  异步任务异常处理
 * @date 2013-11-4下午5:43:32
 */
public abstract class SafeAsyncTask<ResultT> implements Callable<ResultT> {
	public static final int DEFAULT_POOL_SIZE = 25;
	protected static final Executor DEFAULT_EXECUTOR = Executors.newFixedThreadPool(DEFAULT_POOL_SIZE);

	protected Handler handler;
	protected Executor executor;
	protected StackTraceElement[] launchLocation;
	protected FutureTask<Void> future;


	/**
	 * Sets executor to Executors.newFixedThreadPool(DEFAULT_POOL_SIZE) and
	 * Handler to new Handler()
	 */
	public SafeAsyncTask() {
		this.executor = DEFAULT_EXECUTOR;
	}

	/**
	 * Sets executor to Executors.newFixedThreadPool(DEFAULT_POOL_SIZE)
	 */
	public SafeAsyncTask(Handler handler) {
		this.handler = handler;
		this.executor = DEFAULT_EXECUTOR;
	}

	/**
	 * Sets Handler to new Handler()
	 */
	public SafeAsyncTask(Executor executor) {
		this.executor = executor;
	}

	public SafeAsyncTask(Handler handler, Executor executor) {
		this.handler = handler;
		this.executor = executor;
	}


	public FutureTask<Void> future() {
		future = new FutureTask<Void>(newTask());
		return future;
	}

	public SafeAsyncTask<ResultT> executor(Executor executor) {
		this.executor = executor;
		return this;
	}

	public Executor executor() {
		return executor;
	}

	public SafeAsyncTask<ResultT> handler(Handler handler) {
		this.handler = handler;
		return this;
	}

	public Handler handler() {
		return handler;
	}

	public void execute() {
		execute(Thread.currentThread().getStackTrace());
	}

	protected void execute(StackTraceElement[] launchLocation) {
		this.launchLocation = launchLocation;
		executor.execute(future());
	}

	public boolean cancel(boolean mayInterruptIfRunning) {
		if (future == null) throw new UnsupportedOperationException("You cannot cancel this task before calling future()");

		return future.cancel(mayInterruptIfRunning);
	}


	/**
	 * @throws Exception, captured on passed to onException() if present.
	 */
	protected void onPreExecute() throws Exception {
	}

	/**
	 * @param t the result of {@link #call()}
	 * @throws Exception, captured on passed to onException() if present.
	 */
	@SuppressWarnings({"UnusedDeclaration"})
	protected void onSuccess(ResultT t) throws Exception {
	}

	/**
	 * Called when the thread has been interrupted, likely because
	 * the task was canceled.
	 * <p/>
	 * By default, calls {@link #onException(Exception)}, but this method
	 * may be overridden to handle interruptions differently than other
	 * exceptions.
	 *
	 * @param e an InterruptedException or InterruptedIOException
	 */
	protected void onInterrupted(Exception e) {
		onException(e);
	}

	/**
	 * Logs the exception as an Error by default, but this method may
	 * be overridden by subclasses.
	 *
	 * @param e the exception thrown from {@link #onPreExecute()}, {@link #call()}, or {@link #onSuccess(Object)}
	 * @throws RuntimeException, ignored
	 */
	protected void onException(Exception e) throws RuntimeException {
		onThrowable(e);
	}

	protected void onThrowable(Throwable t) throws RuntimeException {
		Log.e("roboguice", "Throwable caught during background processing", t);
	}

	/**
	 * @throws RuntimeException, ignored
	 */
	protected void onFinally() throws RuntimeException {
	}


	protected Task<ResultT> newTask() {
		return new Task<ResultT>(this);
	}


	public static class Task<ResultT> implements Callable<Void> {
		protected SafeAsyncTask<ResultT> parent;
		protected Handler handler;

		public Task(SafeAsyncTask<ResultT> parent) {
			this.parent = parent;
			this.handler = parent.handler != null ? parent.handler : new Handler(Looper.getMainLooper());
		}

		public Void call() throws Exception {
			try {
				doPreExecute();
				doSuccess(doCall());

			} catch (final Exception e) {
				try {
					doException(e);
				} catch (Exception f) {
					// logged but ignored
					Log.e("BACKGROUND_TASK", "Exception in", f);
				}

			} catch (final Throwable t) {
				try {
					doThrowable(t);
				} catch (Exception f) {
					// logged but ignored
					Log.e("BACKGROUND_TASK", "Exception in", f);
				}
			} finally {
				doFinally();
			}

			return null;
		}

		protected void doPreExecute() throws Exception {
			postToUiThreadAndWait(new Callable<Object>() {
				public Object call() throws Exception {
					parent.onPreExecute();
					return null;
				}
			});
		}

		protected ResultT doCall() throws Exception {
			return parent.call();
		}

		protected void doSuccess(final ResultT r) throws Exception {
			postToUiThreadAndWait(new Callable<Object>() {
				public Object call() throws Exception {
					parent.onSuccess(r);
					return null;
				}
			});
		}

		protected void doException(final Exception e) throws Exception {
			if (parent.launchLocation != null) {
				final ArrayList<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(e.getStackTrace()));
				stack.addAll(Arrays.asList(parent.launchLocation));
				e.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
			}
			postToUiThreadAndWait(new Callable<Object>() {
				public Object call() throws Exception {
					if (e instanceof InterruptedException || e instanceof InterruptedIOException) parent.onInterrupted(e);
					else parent.onException(e);
					return null;
				}
			});
		}

		protected void doThrowable(final Throwable e) throws Exception {
			if (parent.launchLocation != null) {
				final ArrayList<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(e.getStackTrace()));
				stack.addAll(Arrays.asList(parent.launchLocation));
				e.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
			}
			postToUiThreadAndWait(new Callable<Object>() {
				public Object call() throws Exception {
					parent.onThrowable(e);
					return null;
				}
			});
		}

		protected void doFinally() throws Exception {
			postToUiThreadAndWait(new Callable<Object>() {
				public Object call() throws Exception {
					parent.onFinally();
					return null;
				}
			});
		}


		/**
		 * Posts the specified runnable to the UI thread using a handler,
		 * and waits for operation to finish.  If there's an exception,
		 * it captures it and rethrows it.
		 *
		 * @param c the callable to post
		 * @throws Exception on error
		 */
		protected void postToUiThreadAndWait(final Callable c) throws Exception {
			final CountDownLatch latch = new CountDownLatch(1);
			final Exception[] exceptions = new Exception[1];

			// Execute onSuccess in the UI thread, but wait
			// for it to complete.
			// If it throws an exception, capture that exception
			// and rethrow it later.
			handler.post(new Runnable() {
				public void run() {
					try {
						c.call();
					} catch (Exception e) {
						exceptions[0] = e;
					} finally {
						latch.countDown();
					}
				}
			});

			// Wait for onSuccess to finish
			latch.await();

			if (exceptions[0] != null) throw exceptions[0];

		}

	}

}

======================================================================================================================================================================================
具体用法如下和AsyncTask类似
private class CountryAsyncTask extends SafeAsyncTask<List<String>> {
		private boolean showLoading;
		public CountryAsyncTask(boolean showLoading) {
			this.showLoading = showLoading;
		}

		@Override
		protected void onPreExecute() throws Exception {
			super.onPreExecute();
			if(showLoading) {
				loadingDialog.show();
			}
		}

		@Override
		public List<String> call() throws Exception {
			List<String> result = null;
			switch(pager) {
				case 0:
					result = firstList;
				break;
				case 1:
					result = secondList;
				break;
				case 2:
					result = thirdList;
				break;
			}
			Thread.sleep(3000);
			return result;
		}

		@Override
		protected void onSuccess(List<String> newItems) throws Exception {
			super.onSuccess(newItems);
			pager++;
			if(listView.getAdapter() == null) {
				listView.setAdapter(adapter);
			}
			listView.onFinishLoading(true, newItems);
		}

		@Override
		protected void onFinally() throws RuntimeException {
			super.onFinally();
			if(loadingDialog.isShowing()) {
				loadingDialog.dismiss();
			}
		}
	}

 

分享到:
评论

相关推荐

    AsyncTask类实例详解

     AsyncTask约定了在子线程中执行任务的抽象方法,开发者可以在自定义AsyncTask的实现类中重写该方法,  则AsyncTask在工作时会自动开启子线程执行相关代码 AsyncTask类的声明:  public abstract class ...

    Android AsyncTask详解及使用方法

    一、自定义AsyncTask 要自定义一个AsyncTask,可以写一个类,继承AsyncTask。例如: ```java class MyAsyncTask extends AsyncTask, Integer, String&gt; { // ... } ``` 其中,第一个参数为doInBackground中传入的...

    WeChatVideoView-Android - 微信 - 朋友圈 - 小视频播放.zip

    技术点 (可以不看)1,下载操作:自定义 AsyncTask。PS:AsyncTask 比 Thread handler 重量级却方便(回调进度),但是,如果是 即放即用,结束即销毁,那么,no need to think about this;2,视频播放组合拳: ...

    listview实现图片的异步加载.zip

    比如,对于简单需求,可以自定义AsyncTask;对于更复杂的应用场景,推荐使用成熟的图片库。 这个压缩包中的源码说明.txt文件应该详细解释了如何使用和理解代码,而点这里查看更多优质源码~.url可能是指向更多类似...

    安卓异步下载到本地Sd卡

    `SyncTask`可能是我们用于实现这个功能的自定义AsyncTask类。 1. **AsyncTask**: - AsyncTask包含三个泛型参数:Params, Progress, Result,分别代表输入参数类型、进度类型和结果类型。 - 它有四个主要方法:`...

    mockandroidasynctask:如何在测试过程中模拟Android AsyncTask

    现在,你的自定义AsyncTask应该继承自`TestableAsyncTask`。在测试过程中,你可以设置一个模拟的回调,以监控任务的完成情况。例如: ```java @Test public void testMyAsyncTask() { MyAsyncTask myTask = new ...

    异步任务AsyncTask

    // 自定义方法,下载图片 return bitmap; } @Override protected void onProgressUpdate(Integer... values) { progressBar.setProgress(values[0]); } @Override protected void onPostExecute(Bitmap ...

    01_AsyncTask_演示线程阻塞

    1. 使用`ExecutorService`自定义线程池,通过`executeOnExecutor()`方法启动`AsyncTask`,控制并发数量。 2. 在适当的地方取消任务,如在`onPause()`或`onDestroy()`中调用`cancel()`方法。 3. 如果任务依赖于网络...

    封装AsyncTask

    例如,通过实现接口或继承自自定义基类,可以提供更灵活的回调机制,以适应不同的应用场景。 在"AsyncTaskDemo"中,我们可以看到具体的实现示例,这可能包括如何创建一个可重用的AsyncTask类,以及如何在实际项目中...

    AsyncTask使用及源码解析

    因此,在处理大量并发任务时,开发者可能需要自定义线程池。 总的来说,AsyncTask是Android开发中处理异步任务的重要工具,它简化了多线程编程,使得开发者能够更方便地在后台执行任务并更新UI。理解AsyncTask的...

    AsyncTask的使用及ListView的常见优化

    我们需自定义一个`BitmapLruCache`类,继承`LruCache, Bitmap&gt;`,并重写`sizeOf()`方法以计算每个Bitmap的大小。然后在应用启动时实例化并设置给`ImageLoader`,当缓存满时,会自动移除最近最少使用的图片,为新的...

    AsyncTask下载网络图片 进度条提示

    因此,我们需要自定义一个进度值,比如下载的字节数,然后根据总字节数计算出百分比,通过`publishProgress()`传递到UI线程。 4. `onProgressUpdate(Progress...)`: 这个方法在主线程中运行,可以用来更新UI,例如...

    AsyncTask 与Thread加Handler处理消息比较

    `Thread+Handler`可以自定义线程池,适合大量并发任务。 4. **更新UI**:`AsyncTask`内置了更新UI的支持,`Thread+Handler`则需要手动处理。 在选择使用哪种方式时,开发者需要根据任务的特性和需求来权衡。对于...

    android asyncTask

    为了解决这个问题,开发者可以选择自定义线程池或者使用其他异步处理框架,如`Handler`、`Loader`、`LiveData`、`Retrofit`、`Coroutines`等。 在提供的`dialogTest`压缩包文件中,可能包含了一个关于如何在`...

    Android用AsyncTask异步加载图片(新)

    但理解`AsyncTask`的基本原理对于自定义实现或优化现有加载逻辑是十分必要的。 `AsyncNetPhoto`这个文件可能包含了实现上述功能的示例代码,你可以参考其源码学习如何在实际项目中应用`AsyncTask`加载网络图片。...

    android较轻级异步任务AsyncTask

    如果需要并行处理,可以自定义线程池。 - **生命周期**:不要在广播接收器或服务中使用`AsyncTask`,因为它们的生命周期不受控制,可能导致资源泄露或任务丢失。 总之,`AsyncTask`是Android中处理简单异步任务的...

    AsyncTask使用实例

    如果需要并行执行更多任务,可以自定义Executor。 - **版本兼容性**:从Android 3.0(API级别11)开始,AsyncTask的执行模式改为序列化,即同一时间只有一个任务会被执行。在低版本系统中,如果需要并行执行,需手动...

    okHttp+AsyncTask封装请求框架不需手动解析

    此外,OkHttp的拦截器机制允许开发者在请求和响应的过程中插入自定义逻辑,如添加请求头、修改请求体或处理响应。 在本封装框架中,OkHttp被用来发起网络请求,通过其Builder模式配置各种参数,如设置超时时间、...

    AsyncTask 源码解析

    但开发者可以自定义线程池,以适应不同的并发需求。 在执行过程中,AsyncTask 通过 Handler 和 Looper 的机制与 UI 线程通信。Handler 发送消息到 Looper 的消息队列,Looper 会按照顺序处理这些消息,确保在 UI ...

    AsyncTask_ListView实现加载网络图片例子

    接下来,我们将创建一个自定义的Adapter,它将负责加载网络图片并将其显示在ListView的每一项中。Adapter通常继承自BaseAdapter或ArrayAdapter,我们这里可以创建一个继承自BaseAdapter的类,包含一个List来存储图片...

Global site tag (gtag.js) - Google Analytics