Android_AsyncTask 痛定思痛。 2022-09-24 11:26 197阅读 0赞 **我们都知道AsyncTask是为了异步而生** **所以为什么要异步任务:** A: android是单线程模型 B: 耗时操作要放在非主线程中执行 首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。 因为我今天只看了异步的AsyncTask所以这篇就只涉及到AsyncTask: **AsyncTask**,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程. 看一下构建AsyncTsak子类的参数 AsyncTsak <Params,progress,Result> AsyncTsak 是一个抽象类 通常用于被继承 继承AsyncTsak需要指定如下三个泛型参数: **Params:启动任务时输入参数的类型。** **progress: 后台任务执行中返回进度值得类型** **Result: 后台执行任务完成后返回结果的类型** 构建AsyncTsak之类的回调方法: **doInBackground()**:**必须重写的,**异步执行后台线程将要完成的任务 所有的耗时操作都在这里 **onPreExecute()**:执行后台耗时操作之前被调用通常用户完成一些初始化操作 **onPostExecute()**:当doInBackground()完成后 系统会自动调用onPostExecute()方法 并将doInBackground()方法返回的值传给这个方法 **onProgressUpdate()**:在doInBackground()方法中调用publishProgress()方法更新任务的执行进度后,就会触发这个方法 所以我创建了一段代码我们来看一下他的执行顺序 public class MyAsyncTask extends AsyncTask { @Override protected void onProgressUpdate(Object[] values) { Log.e("qwe","onProgressUpdate"); super.onProgressUpdate(values); } @Override protected void onPostExecute(Object o) { Log.e("qwe","onPostExecute"); super.onPostExecute(o); } @Override protected void onPreExecute() { Log.e("qwe","onPreExecute"); super.onPreExecute(); } @Override //必须实现的方法 protected Object doInBackground(Object[] params) { Log.e("qwe","doInBackground"); return null; } } 这段代码运行控制台的截图是这样的 ![这里写图片描述][20160730002242738] 清楚的看到 调用顺序是onPostExecute——doInBackground——onPostExecute和我们说的一样啦 就是先初始化然后doInBackground然后把结果传递到onPostExecute去更新UI 对 还有一个方法我们没有见到onProgressUpdate 因为我们并没有调用他啊 所以现在我们在 doInBackground中加入这个方法 @Override //必须实现的方法 protected Object doInBackground(Object[] params) { publishProgress(); Log.e("qwe","doInBackground"); return null; } 运行结果就是这样啦 ![这里写图片描述][20160730002803072] 清楚的看到 调用顺序是onPostExecute——doInBackground——onProgressUpdate ——onPostExecute 大概就这么多 要看一个例子: 网络操作是很耗时的也很不稳定的 禁止在主线程中进行网络操作 、所以例子就是 异步操作—下载图像 在UI线程—设置图像 提前准备一张图片 我就用上面结果的截图吧 url在这里:[https://img-blog.csdn.net/20160729204939361][https_img-blog.csdn.net_20160729204939361] package com.example.katherine_qj.asynctask; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; /** * Created by Katherine-qj on 2016/7/29. */ public class ImageTest extends Activity { private ImageView imageView; private ProgressBar progressBar; private static String url = "https://img-blog.csdn.net/20160729204939361"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image_asyncatask); InitView(); //设置传递进去的参数 new MyAsycTaskImage().execute(url); } public void InitView() { imageView = (ImageView)findViewById(R.id.image); progressBar = (ProgressBar)findViewById(R.id.progressbar); } class MyAsycTaskImage extends AsyncTask<String,Void,Bitmap>{ @Override protected Bitmap doInBackground(String... params) { //传入的是一个可变数组 String url = params[0];//取出传递进来的对应的url; Bitmap bitmap = null; URLConnection connection ; InputStream is ; try { connection = new URL(url).openConnection(); is = connection.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } bitmap = BitmapFactory.decodeStream(bis);//通过decodeStream方法解析输入流 bis.close();//以上都是访问网络的耗时操作 } catch (IOException e) { e.printStackTrace(); } return bitmap; } @Override protected void onPreExecute() { super.onPreExecute(); progressBar.setVisibility(View.VISIBLE);//显示进度条 } @Override protected void onPostExecute(Bitmap bitmap) { //操作UI显示图像 super.onPostExecute(bitmap); imageView.setImageBitmap(bitmap); progressBar.setVisibility(View.GONE); } @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); } } } 结果就是 进度条转一会然后图片就加载出来了 例子很简单 但是方法基本都用到了包括了 **注意** 1.要加联网权限: <uses-permission android:name="android.permission.INTERNET"></uses-permission> 2.AsyncTask在主线程中创建和调用 3.重写四个方法 系统自己调用而不是手动调用 4 只能被调用一次 **5.还有就是如果要结束这个AsyncTask** **要先把当前这个AsyncTask标记为cancel状态 然后在每一个** **逻辑中去判断这个状态如果是cancel就做相应的处理** **发送cancel请求将这个AsyncTask标记为cancel状态,并** **没有真正取消** over! 这就是今天下午学到的东西 大概总结下来就这些了 感觉学了这么久还是啥都不会 好焦急 所以明天也好好学习吧 嗯 要加油 [20160730002242738]: /images/20220719/41073f5876da45a1aa5178f2ed3f3c6d.png [20160730002803072]: /images/20220719/67d4fc862d9c4b27829c8fc6d0507c58.png [https_img-blog.csdn.net_20160729204939361]: https://img-blog.csdn.net/20160729204939361
还没有评论,来说两句吧...