AsyncTask 里面添加进度条
- 格式:wps
- 大小:26.50 KB
- 文档页数:3
Android开发如何执行后台异步任务(AsyncTask实现)在Android开发中,经常要用到一些联网等长时间的操作,比如说联网下载图片或下载文件,如果文件较大就会需要较长的下载时间,如果直接顺序执行的话,界面可能就不动了,这样的用户体验很不好,为了有更好的用户体验,我们可以在下载开始后给用户提示一个进度条或者说一个等待提示,这里我们可以用后台异步任务来实现这些操作。
我们在用eclipse新建Activity的时候,可以选择LoginActivity模版,这样生成的Activity会自动生成有登录操作的异步任务模版,我们可以适当修改适应我们的需求即可。
我们在执行后台任务时,弹出一个进度框ProgressDialog,给用户提供一种更好的体验:ProgressDialog progress = new ProgressDialog(this);progress.setMessage("Please wait ...");我们要执行的后台任务通过继承AsyncTask类来实现,并重写doInBackground、onPostExecute两个方法,doInBackground方法执行后台任务,onPostExecute方法为任务执行后处理。
AsyncTask类的详细介绍可参考官方文档:/reference/android/os/AsyncTask.htm。
class LoginTask extends AsyncTask<Void, Void, Boolean> {@Overrideprotected Boolean doInBackground(Void... args) {// 要执行的后台任务,登录、联网查询等。
return true;}@Overridepublic void onPostExecute(Boolean result) {task = null;progress.dismiss();if (result) {Toast.makeText(LoginActivity.this, "Success .", Toast.LENGTH_LONG).show();} else {Toast.makeText(LoginActivity.this, "Failed !", Toast.LENGTH_LONG).show();}}}在AsyncTask中,第一个Void是参数的类型,如果在执行任务的时候需要传递参数,可以改变这个类型,相应的doInBackground的参数类型也要改变;第二个Void是任务执行的进度,可以根据这个值控制进度条的提示;第三个Boolean是后台任务执行的返回结果,这里使用Boolean类型,根据返回的true/false判断任务是否执行成功,如果需要修改则onPostExecute方法的参数也要相应修改。
多线程异步处理:AsyncTask异步更新UI界面(详细完整总结篇)转载自:/mylzc/article/details/6772129 ,在原先的基础上整理项目并重新发布。
AsyncTask的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后使用Thread+Handler的方式调用回调函数。
AsyncTask抽象出后台线程运行的五个状态,分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务,对于这五个阶段,AsyncTask提供了五个回调方法:1、准备运行:onPreExecute(),该回调方法在任务被执行之后立即由UI线程调用。
这个步骤通常用来建立任务,在UI上显示进度条。
2、正在后台运行:doInBackground(Params...),该回调方法由后台线程在onPreExecute()方法执行结束后立即调用。
通常在这里执行耗时的后台计算,计算的结果必须由该方法返回,并被传递到onPostExecute()中。
在该方法内也可使用publishProgress(Progress...)来发布一个或多个进度单位(units of progress),这些值将会在onProgressUpdate(Progress...)中被发布到UI线程。
3. 进度更新:onProgressUpdate(Progress...),该方法由UI线程在publishProgress(Progress...)方法调用完后被调用,一般用于动态地显示一个进度条。
4. 完成后台任务:onPostExecute(Result),当后台计算结束后调用。
后台计算的结果会被作为参数传递给该方法。
5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用AsyncTask的构造函数有三个模板参数:1.Params:传递给后台任务的参数类型。
2.Progress :后台计算执行过程中,进步单位(progress units )的类型(就是后台程序已经执行了百分之几了)。
麦可网android教育 Android AsyncTask详解1. 在AsyncTask中,耗时任务在子线程中执行,回调方法在主线程中执行。
2. AsyncTask定义:private class AsyncLoadingTask extends AsyncTask{ @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Result doInBackground(Params... params) { return null; } @Override protected void onProgressUpdate(Progress... progress) { super.onProgressUpdate(progress); } @Override protected void onPostExecute(Result result) { super.onPostExecute(result); } @Override protected void onCancelled() { super.onCancelled(); } }范型定义:(1) Params:启动任务时的输入参数,比如:HTTP请求的URL,组件对象。
(2) Progress:任务执行的进度,比如:Integer对象(进度值)。
(3) Result:任务执行結果,比如:Bitmap对象(从网上获取的图片)。
3. AsyncTask的方法:(1) onPreExecute()方法:任务刚启动时调用些方法,完成初始化操作,在UI线程中执行。
(2) doInBackground()方法:执行任务的主要方法,在子线程执行。
(3) onProgressUpdate()方法:在doInBackground()调用publicProgress(Progress... progress)方法后调用,进行UI进度更新,在UI线程中执行。
android asynctask用法Android AsyncTask是Android开发中的一个重要概念和工具,用于在后台线程执行耗时操作并在主线程更新UI。
本文将逐步介绍AsyncTask的用法和一些注意事项。
第一部分:AsyncTask的介绍在Android中,当某些操作比如网络请求、文件读写或数据库访问等需要耗费较长时间时,我们需要将这些操作放在后台线程中执行,以免阻塞主线程导致UI 卡顿。
而AsyncTask正是Android官方提供的一个解决方案,它封装了线程的管理和消息传递的机制,使得开发者能够更方便地进行异步操作。
第二部分:AsyncTask的基本结构AsyncTask是一个抽象类,需要通过继承来使用。
在继承AsyncTask时,我们需要指定三个泛型参数,分别是Params、Progress和Result。
Params指定了输入参数的类型,Progress指定了进度更新的类型,Result指定了结果返回的类型。
在实际使用时,我们可以根据具体需求将这些参数设置为具体的类型。
第三部分:AsyncTask的几个重要方法在AsyncTask中,有几个重要的方法需要注意。
首先是onPreExecute()方法,它会在执行异步任务之前被调用,通常用来做一些准备工作,比如显示进度条。
然后是doInBackground()方法,它被执行在后台线程中,用于执行耗时操作。
在这个方法中,我们可以通过调用publishProgress()方法来更新进度。
最后是onPostExecute()方法,它在耗时操作执行完毕后被调用,在这个方法中我们可以更新UI或者做一些后续操作。
第四部分:AsyncTask的使用步骤使用AsyncTask的步骤分为以下几个:1. 继承AsyncTask并指定泛型参数;2. 在onPreExecute()中进行一些准备工作;3. 在doInBackground()中执行耗时操作;4. 在publishProgress()中更新进度;5. 在onPostExecute()中处理耗时操作执行完毕后的结果。
Android AsyncTask解析我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制,参考之前一篇文章Android 异步消息处理机制:Looper、Handler、Message。
但是费时的任务操作总会启动一些匿名的子线程,太多的子线程会给系统带来巨大的负担,随之带来一些性能问题。
因此Android提供了一个工具类AsyncTask,顾名思义异步执行任务,使用它就可以非常灵活方便地从子线程切换到UI线程。
AsyncTask的基本用法由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。
在继承时我们可以为AsyncTask类指定三个泛型参数Params,Progress和Result,这三个参数的用途如下:Params传入doInBackground()方法的参数类型。
启动任务执行的输入参数,比如HTTP请求的URL。
Progress传入onProgressUpdate()方法的参数类型。
后台任务执行的百分比。
Result传入onPostExecute()方法的参数类型,也是doInBackground()方法返回的类型。
后台执行任务最终返回的结果,比如String,Integer等AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现这些方法:onPreExecute()该方法将在执行实际的后台操作前被UI 线程调用。
可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
doInBackground(Params…)将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。
这里将主要负责执行那些很耗时的后台处理工作。
可以调用publishProgress方法来更新实时的任务进度。
该方法是抽象方法,子类必须实现。
关于unity3D异步加载进度条实时更新的⽅法在其他地⽅看到所谓的实时更新就是让slider的当前value等于异步对象的进度值⽽已,太坑了,这个正常来理解的意思不就是从0开始递增到100嘛,不管怎么我已经完成这个功能了,代码贴上,以免⽇后忘记,找到这篇博客的朋友算你好运,直接搬⾛吧(NGUI版)~需要重点提醒的:异步对象AsyncOperation的值到90%后不会再增长,剩下的10%要让AsyncOperation.allowSceneActivation(意思是场景加载完毕后⾃动跳转场景)为true时才会⾃动完成~完整代码下⽅贴上:using UnityEngine;using System.Collections;public class Loading : MonoBehaviour {private AsyncOperation async;public UISlider slider;// Use this for initializationvoid Start (){StartCoroutine (loadScene ());}// Update is called once per framevoid Update () {if (async != null){if(!async.isDone){if(slider.value<=.9f){if(slider.value <= async.progress){slider.value += Time.deltaTime;}}else{if(slider.value<1f){slider.value += Time.deltaTime;}else{async.allowSceneActivation = true;}}}}}IEnumerator loadScene(){async = Application.LoadLevelAsync (Globe.loadName);async.allowSceneActivation = false;yield return async;}。
.net core async task的用法.NET Core Async Task的用法在 .NET Core 中,异步操作已经成为了一种标准的编程模式。
在进行异步操作时,我们经常使用 Task 和async/await 关键字,无论是进行 I/O 操作、数据处理,还是进行 CPU 密集型的计算。
Task 是框架提供的一种封装,用于抽象化异步操作。
它的作用是表示一项操作的异步进程,可以用于实现多任务并发编程,与线程池相比,使用多个 Task 可以更好地协同工作、更高效地处理工作负载。
本文将介绍一下 Task 使用中的常见问题及解决方案。
创建TaskTask 的创建方法主要有以下几种:1. Task.Run(),可以通过这种方式在新的线程上执行一个函数,并同时返回 Task 对象。
例如,如果我们想要将一个函数 f() 运行在其他的线程上,并通过 Task 构建异步过程,可以使用 Task.Run ()来创建一个 Task 对象,如下所示:``` using System.Threading.Tasks;Task task = Task.Run(() => { f(); }); ```2. Task.Factory.StartNew(),用于基于操作异步启动一个新的 Task,这种方式可以控制线程的创建与使用。
例如,如果我们想要创建一个去执行一些异步操作的Task,可以使用 Task.Factory.StartNew 方法,如下所示:``` Task task = Task.Factory.StartNew(() => { f(); }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); ```3. TaskCompletionSource,可以通过TaskCompletionSource 来创建一个新的 Task 实例,我们可以手动设置它的状态和结果。
Android开发——AsyncTask的使用以及源码解析1.1 AsyncTask实例使用下面是一个使用AsyncTask的实例,通过指定URL利用网络下载资源(此例模拟资源为字符串),以模拟耗时任务。
在下载过程中,会通过进度条对话框向用户展示进度。
在完成任务后将字符串展示在TextView上。
具体实现细节后面会加以讲述,顺便引出AsyncTask的知识。
[java] view plain copy 在CODE上查看代码片派生到我的代码片public class MainActivity extends Activity{private TextView show;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(yout.main);show = (TextView) findViewById(R.id.show);}//按钮事件响应方法URL可自定义public void download(View source) throws Exception{DownTask task = new DownTask(this);task.execute(new URL(URL));}class DownTask extends AsyncTask<URL, Integer, String>{ //自定义Task类继承AsyncTaskProgressDialog pdialog;int hasRead = 0;Context mContext;public DownTask(Context ctx){mContext = ctx;}@Overrideprotected String doInBackground(URL... params){ //doInBackground方法在子线程执行耗时任务StringBuilder sb = new StringBuilder();try{URLConnection conn = params[0].openConnection();BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));String line = null;while ((line = br.readLine()) != null){sb.append(line + "\n");hasRead++;publishProgress(hasRead);}return sb.toString();}catch (Exception e){e.printStackTrace();}return null;}@Overrideprotected void onPostExecute(String result){ //主线程执行// 展示下载下来的字符串并将进度条对话框dismissshow.setText(result);pdialog.dismiss();}@Overrideprotected void onPreExecute(){ //主线程执行pdialog = new ProgressDialog(mContext);pdialog.setTitle("任务正在执行中");pdialog.setMessage("请等待...");// 设置对话框不能用“取消”按钮关闭pdialog.setCancelable(false);pdialog.setMax(MAX);// 设置对话框的进度条风格pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 设置对话框的进度条是否显示进度pdialog.setIndeterminate(false);pdialog.show();}@Overrideprotected void onProgressUpdate(Integer... values){ //主线程执行// 更新进度show.setText("已经读取了" + values[0] + "行");pdialog.setProgress(values[0]);}}}1.2 AsyncTask参数介绍看了上面的例子,我们会解释例子中涉及到的AsyncTask知识,首先是参数介绍:AsyncTask定义了三种泛型类型Params,Progress和Result。
asynctask的高级用法Asynctask的高级用法Asynctask是Android提供的一个异步处理框架,可以方便地在前台线程执行后台任务并把结果更新到UI线程。
尽管Asynctask已经被标记为“已过时”,但它仍然是很多基于旧版Android系统的应用程序中执行异步任务的首选方法。
本文将介绍Asynctask的高级用法,包括线程池技术、并行执行、超时机制和取消任务等。
线程池技术Asynctask默认使用单独的线程来执行任务,但是在实际应用中,由于系统资源限制和任务数量不断增加,很容易导致线程池不足,从而影响应用程序的性能。
为此,可以使用线程池技术来提高线程池的利用率。
线程池技术基于线程重用的原则,每当新任务到来时,首先从线程池中获取一个空闲线程来执行该任务,当任务结束后,该线程将返回线程池以备新任务继续使用。
线程池可以有效地降低线程创建和销毁的开销,减少线程数的过度增长,并提高应用程序的稳定性和响应速度。
在Asynctask中,可以通过使用ThreadPoolExecutor类来创建线程池,并使用execute()方法来提交任务到线程池。
以下是基于线程池技术的Asynctask的示例代码。
public class MyAsyncTask extends AsyncTask<Void, Void, String> { private Executor mExecutor;public MyAsyncTask() {mExecutor = Executors.newCachedThreadPool();}@Overrideprotected String doInBackground(Void... params) {执行后台任务return "success";}@Overrideprotected void onPostExecute(String result) {更新UI界面}public void start() {executeOnExecutor(mExecutor); 提交任务到线程池}}并行执行Asynctask默认是串行执行任务,即一个任务完成后才能执行下一个任务。
springboot利⽤aop实现接⼝异步(进度条)的全过程⽬录⼀、前⾔⼆、时序图三、功能演⽰四、关键代码ControllerAsyncAopAsyncService五、源码地址总结⼀、前⾔在项⽬中发现有接⼝(excel导⼊数据)处理数据需要耗时⽐较长的时间,是因为数据量⽐较⼤,同时数据的校验需要耗费⼀定时间,决定使⽤⼀种通⽤的⽅法解决这个问题。
解决⽅案:通过aop使接⼝异步处理,前端轮询另外⼀个接⼝查询进度。
⽬标:1接⼝上⼀个注解即可实现接⼝异步(优化:可以通过header参数动态控制是否异步)2⼀个⽅法实现进度条的更新⼆、时序图三、功能演⽰四、关键代码Controller@EnableAsync是⾃已定义注解更新缓存进度asyncService.updatePercent(per);@EnableAsync@RequestMapping(value = "test", method = RequestMethod.POST)@ApiOperation(value = "接⼝测试")@ApiImplicitParams({@ApiImplicitParam(name = "num", value = "数字", required = true, dataType = "int", paramType = "query", defaultValue = "1")})public Object demo(Integer num) throws InterruptedException {for (int i = 0; i < 15; i++) {Thread.sleep(1000);//计算百分⽐String per = BigDecimal.valueOf(i).divide(BigDecimal.valueOf(15), 2, RoundingMode.HALF_DOWN).toString();//更新redis缓存进度asyncService.updatePercent(per);}Integer b = 100;return Result.success(String.format("线程变量值:%s,100除以%s的结果是%s", RequestHolder.get(), num, b / num));}AsyncAopimport cn.hutool.core.util.IdUtil;import mon.Result;import mon.pojo.RequestHolder;import com.asyf.demo.service.AsyncService;import lombok.extern.slf4j.Slf4j;import ng.ProceedingJoinPoint;import ng.annotation.Around;import ng.annotation.Aspect;import ng.annotation.Pointcut;import ng.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import ponent;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;@Aspect@Component@Slf4jpublic class AsyncAop {@Autowiredprivate AsyncService asyncService;@Pointcut("@annotation(mon.aop.EnableAsync)")public void costTimePointCut() {}@Around("costTimePointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {long beginTime = System.currentTimeMillis();//请求headerServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = servletRequestAttributes.getRequest();RequestHolder.set(request.getHeader("dateFormat"));//异步消息String id = IdUtil.simpleUUID();AsyncMsg asyncMsg = new AsyncMsg();asyncMsg.setId(id);//异步返回值Object result = Result.success(asyncMsg);String requestHolder = RequestHolder.get();//异步执⾏asyncService.async(requestHolder, asyncMsg, point);//执⾏时长(毫秒)long time = System.currentTimeMillis() - beginTime;logCostTime(point, time);return result;}private void logCostTime(ProceedingJoinPoint point, long time) {MethodSignature signature = (MethodSignature) point.getSignature();String className = point.getTarget().getClass().getName();String methodName = signature.getName();("class:{} method:{} 耗时:{}ms", className, methodName, time);}}AsyncService实现异步消息的更新异步消息的进度信息传递通过本地线程与redis实现import cn.hutool.core.exceptions.ExceptionUtil;import mon.aop.AsyncMsg;import mon.pojo.AsyncHolder;import mon.pojo.RequestHolder;import com.asyf.demo.service.AsyncService;import lombok.extern.slf4j.Slf4j;import ng.ProceedingJoinPoint;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service@Slf4jpublic class AsyncServiceImpl implements AsyncService {@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic void async(String requestHolder, AsyncMsg asyncMsg, ProceedingJoinPoint point) {new Thread(new Runnable() {@Overridepublic void run() {String id = asyncMsg.getId();//请求线程变量-传递请求线程参数RequestHolder.set(requestHolder);//异步消息线程变量-传送id到实际⽅法以便⽅法更新进度AsyncHolder.set(asyncMsg);//执⾏⽅法try {redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES);Object result = point.proceed();asyncMsg.setResult(result);asyncMsg.setStatus("0");redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES);} catch (Throwable throwable) {log.error(ExceptionUtil.stacktraceToString(throwable));asyncMsg.setStatus("-1");asyncMsg.setResult(throwable.getLocalizedMessage());redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES);}}}).start();}@Overridepublic void updatePercent(String per) {AsyncMsg asyncMsg = AsyncHolder.get();asyncMsg.setPercent(per);redisTemplate.opsForValue().set(asyncMsg.getId(), asyncMsg, 60, TimeUnit.MINUTES);}}五、源码地址java-demo: 存储代码⽰例 - 总结到此这篇关于springboot利⽤aop实现接⼝异步(进度条)的⽂章就介绍到这了,更多相关springboot aop实现接⼝异步内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
AsyncTask 里面添加进度条
很多网上进度条的demo都是handl er的。
但是如果用AsyncTask怎么能实现进度条?两种办法,一个是看googl e API 一种是看下面这个demo。
此demo全是核心代码没有废话
public class MainActivity extends Activity {
ProgressBar progressBar;
Button buttonStartProgress;
public class BackgroundAsyncTask extends
AsyncTask<Void, Integer, Void> {
int myProgress;
@Overrid e
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,
"onPostExecute", Toast.LENGTH_LONG).show();
buttonStartProgress.setClickable(true);
}
@Overrid e
protected void onPreExecute() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,
"onPreExecute", Toast.LENGTH_LONG).show();
myProgress = 0;
}
@Overrid e
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
whil e(myProgress<100){
myProgress++;
publishProgress(myProgress);
SystemCl ock.sl eep(100);
}
return null;
}
@Overrid e
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
progressBar.setProgress(values[0]);
}
}
/** Call ed when the activity is first created. */
@Overrid e
public void onCreate(Bundl e savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.activity_main);
buttonStartProgress = (Button)findViewById(R.id.startprogress);
progressBar = (ProgressBar)findViewById(R.id.progressbar_Horizontal); progressBar.setProgress(0);
buttonStartProgress.setOnClickListener(new Button.OnClickListener(){
@Overrid e
public void onClick(View v) {
// TODO Auto-generated method stub
new BackgroundAsyncTask().execute();
buttonStartProgress.setClickable(false);
}});
}
}
在xml里面做如下设置
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hell o"
/>
<Button
android:id="@+id/startprogress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
styl e="?android:attr/progressBarStyl eHorizontal"
android:id="@+id/progressbar_Horizontal"
android:max="100"
/>
</LinearLayout>
由于只有一个类就不上传源码了。
具体要注意的就是继承AsyncTask的时候,所有重写的方法,最好看一眼googl e API
来源:清源教育。