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 ...
一、自定义AsyncTask 要自定义一个AsyncTask,可以写一个类,继承AsyncTask。例如: ```java class MyAsyncTask extends AsyncTask, Integer, String> { // ... } ``` 其中,第一个参数为doInBackground中传入的...
技术点 (可以不看)1,下载操作:自定义 AsyncTask。PS:AsyncTask 比 Thread handler 重量级却方便(回调进度),但是,如果是 即放即用,结束即销毁,那么,no need to think about this;2,视频播放组合拳: ...
比如,对于简单需求,可以自定义AsyncTask;对于更复杂的应用场景,推荐使用成熟的图片库。 这个压缩包中的源码说明.txt文件应该详细解释了如何使用和理解代码,而点这里查看更多优质源码~.url可能是指向更多类似...
`SyncTask`可能是我们用于实现这个功能的自定义AsyncTask类。 1. **AsyncTask**: - AsyncTask包含三个泛型参数:Params, Progress, Result,分别代表输入参数类型、进度类型和结果类型。 - 它有四个主要方法:`...
现在,你的自定义AsyncTask应该继承自`TestableAsyncTask`。在测试过程中,你可以设置一个模拟的回调,以监控任务的完成情况。例如: ```java @Test public void testMyAsyncTask() { MyAsyncTask myTask = new ...
// 自定义方法,下载图片 return bitmap; } @Override protected void onProgressUpdate(Integer... values) { progressBar.setProgress(values[0]); } @Override protected void onPostExecute(Bitmap ...
1. 使用`ExecutorService`自定义线程池,通过`executeOnExecutor()`方法启动`AsyncTask`,控制并发数量。 2. 在适当的地方取消任务,如在`onPause()`或`onDestroy()`中调用`cancel()`方法。 3. 如果任务依赖于网络...
例如,通过实现接口或继承自自定义基类,可以提供更灵活的回调机制,以适应不同的应用场景。 在"AsyncTaskDemo"中,我们可以看到具体的实现示例,这可能包括如何创建一个可重用的AsyncTask类,以及如何在实际项目中...
因此,在处理大量并发任务时,开发者可能需要自定义线程池。 总的来说,AsyncTask是Android开发中处理异步任务的重要工具,它简化了多线程编程,使得开发者能够更方便地在后台执行任务并更新UI。理解AsyncTask的...
我们需自定义一个`BitmapLruCache`类,继承`LruCache, Bitmap>`,并重写`sizeOf()`方法以计算每个Bitmap的大小。然后在应用启动时实例化并设置给`ImageLoader`,当缓存满时,会自动移除最近最少使用的图片,为新的...
因此,我们需要自定义一个进度值,比如下载的字节数,然后根据总字节数计算出百分比,通过`publishProgress()`传递到UI线程。 4. `onProgressUpdate(Progress...)`: 这个方法在主线程中运行,可以用来更新UI,例如...
`Thread+Handler`可以自定义线程池,适合大量并发任务。 4. **更新UI**:`AsyncTask`内置了更新UI的支持,`Thread+Handler`则需要手动处理。 在选择使用哪种方式时,开发者需要根据任务的特性和需求来权衡。对于...
为了解决这个问题,开发者可以选择自定义线程池或者使用其他异步处理框架,如`Handler`、`Loader`、`LiveData`、`Retrofit`、`Coroutines`等。 在提供的`dialogTest`压缩包文件中,可能包含了一个关于如何在`...
但理解`AsyncTask`的基本原理对于自定义实现或优化现有加载逻辑是十分必要的。 `AsyncNetPhoto`这个文件可能包含了实现上述功能的示例代码,你可以参考其源码学习如何在实际项目中应用`AsyncTask`加载网络图片。...
如果需要并行处理,可以自定义线程池。 - **生命周期**:不要在广播接收器或服务中使用`AsyncTask`,因为它们的生命周期不受控制,可能导致资源泄露或任务丢失。 总之,`AsyncTask`是Android中处理简单异步任务的...
如果需要并行执行更多任务,可以自定义Executor。 - **版本兼容性**:从Android 3.0(API级别11)开始,AsyncTask的执行模式改为序列化,即同一时间只有一个任务会被执行。在低版本系统中,如果需要并行执行,需手动...
此外,OkHttp的拦截器机制允许开发者在请求和响应的过程中插入自定义逻辑,如添加请求头、修改请求体或处理响应。 在本封装框架中,OkHttp被用来发起网络请求,通过其Builder模式配置各种参数,如设置超时时间、...
但开发者可以自定义线程池,以适应不同的并发需求。 在执行过程中,AsyncTask 通过 Handler 和 Looper 的机制与 UI 线程通信。Handler 发送消息到 Looper 的消息队列,Looper 会按照顺序处理这些消息,确保在 UI ...
接下来,我们将创建一个自定义的Adapter,它将负责加载网络图片并将其显示在ListView的每一项中。Adapter通常继承自BaseAdapter或ArrayAdapter,我们这里可以创建一个继承自BaseAdapter的类,包含一个List来存储图片...