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类的声明: public abstract class ...
技术点 (可以不看)1,下载操作:自定义 AsyncTask。PS:AsyncTask 比 Thread handler 重量级却方便(回调进度),但是,如果是 即放即用,结束即销毁,那么,no need to think about this;2,视频播放组合拳: ...
Handler,AsyncTask,Looper自定义线程使用示例,自定义线程与UI线程交互,访问UI线程控件
(原创)使用AsyncTask(带修改线程池方式)+自定义ImageLoader+LRU算法对图片三级缓存及其显示优化(只有在ListView滑动停止的时候才去网络请求获取图片数据)...
Android AsyncTask详解及使用... 一、如果想自定义一个AsyncTask,可以写一个类,继承AsyncTask。 eg: 、 //第一个参数为doInBackground中传入的类型,第二个为doInBackground中更新的参数的类型,第三个为do
演示如何将Listview与Viewholder模式,自定义arrayadapter以及使用asynctask从Assets文件夹中加载数据一起使用。 国家/地区数据以csv格式存储,并使用Opencsv( )进行解析。 请注意,该项目是用于课程分配的,并未...
前面一篇博客《AsyncTask实现断点续传》讲解了如何实现单线程下的断点续传,也就是一个文件只有一个线程进行下载。 对于大文件而言,使用多线程下载就会比单线程下载要快一些。多线程下载相比单线程下载要稍微复杂...
【第一部分】历史文章: Android学习笔记(一)——创建第一个Android项目 ...Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务 Android学习笔记(七)——数据存储(共享参数Share
基于多线程、AsyncTask、Adapter、IntentFilter、自定义View、消息队列等技术的一款数字拼图的Android项目
|--Dialog实现无标提栏及自定义风格 |--Dialog风格Activity的作法 |--ExpandableListView(下拉伸缩ListView) |--GridView表格布局的用法 |--httpclient超时 |--info体系 |--Intent启动应用apk安装 |--Intent常用功能...
Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务 Android学习笔记(七)——数据存储(共享参数SharedPreferences) Android学习笔记(八)——数据存储(SD卡文件操作) Android学习笔记(九)——...
基于多线程、AsyncTask、Adapter、IntentFilter、自定义View、消息队列等技术的一款欢乐打地鼠的Android项目
基于IT-ebooks.info API的简单电子书下载器应用程序.. :) 作为大学Android项目的一部分。... 4, 自定义Webview和自定义下载管理器5。 出色的Picasso图像加载程序库与常规AsyncTask图像加载(注释)的某些用法
AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...
AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...
自定义对话框在关闭之前会更改一次状态,所有这些都在 Asynctask 中处理。 该对话框有一个标题和一个不确定的进度条。 2 秒后,对话框的标题更改为完成并且进度条停止。 再过 1 秒后,对话框将自动关闭。
【第一部分】历史文章: Android学习笔记(一)——创建第一个Android项目 ...Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务 Android学习笔记(七)——数据存储(共享参数Share
【第一部分】历史文章: Android学习笔记(一)——创建第一个Android项目 ...Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务 Android学习笔记(七)——数据存储(共享参数Share
16 AsyncTask进度条加载网站数据到ListView 17 EditText插入QQ表情源码 18 OpenGL的一个简单的例子 19闹钟 20 指南针 21 重力感应 22 android 查询工具源代码 23 android进度条对话框Demo 24 Android实现渐显按钮的...