ANR,多线程,Handler,异步加载
来源:互联网 发布:ubuntu的vim怎么装不了 编辑:程序博客网 时间:2024/06/11 19:50
一、ANR(Application Not Responding)
1.什么是ANR异常?
——指应用程序无响应。android程序中会弹出提示dialog,其中一个选项是“等待”,另一个选项是“强制退出”。
2.什么情况下会引发ANR异常?
——android应用程序的响应由ActivityManager和WindowManager来管理和监听。
1)在5秒钟之内没有相应输入事件(如返回键,屏幕触摸)
2)广播在10秒钟之内没有完成逻辑
实际应用中什么情况下会出现ANR:在主线程中执行耗时操作(如文件下载,图片下载,IO异常,数据库操作,高耗时的图片尺寸处理,复杂的视图加载等等)
3.如何解决?
——1)把耗时操作相关的代码写到子线程。(要求主线程的生命周期的方法尽量少做事情)。在android程序中提供了handler+message消息机制,使子线程能够与主线程进行通信。
——2)应用程序应避免在广播(BroadcastReceiver)中执行耗时操作或计算。但不是在子线程中做这些任务(因为BroadcastReceiver生命周期短),如果在intent广播中需要执行耗时操作,可以启动service去做。
——3)避免在intent receiver中启动activity,因为activity会创建新的视图,并且在用户正在运行的应用程序上抢占焦点。如果你的应用程序在相应intent广播时需要向用户展示什么,这个时候应该使用android提供的Notification Manager,把它发到通知栏上,让用户选择是否查看,而不是程序自己打开。因为这样会很卡,造成用户无法点击,用户体验会很差。
二、线程
1.操作系统:实时操作系统,分时操作系统(可以并发做多个任务)。从微观的角度看,操作系统还是实时的,cpu一次只能处理一件事情。但是因为cpu的执行速度是很快的。
2.什么是进程?
——(操作系统)为每一个任务分配一系列的资源(如cpu,内存等)来执行该任务,这就是进程。
3.什么是线程?
——CPU执行的最小的代码段
4.进程与线程的关系?
——进程是炒菜,线程是炒菜的每一个步骤。进程中包含很多线程。
三、Handler
一个Handler允许你发message和runnable对象。每个Handler实例都会关联一个单线程和线程消息队列,当你创建一个新的Hanlder,它就被绑定到当前所在的线程——从那时起,它将提供消息和runnable对象,当消息或runnable从消息队列里面被取出的时候,就会被执行。
一个Handler有两个主要用途:
1)执行调度消息和将要被执行的runnable
2)运行在某个线程上,共享线程的消息队列
四、异步加载(AsyncTask)
这里我们来做一个下载图片的demo。
1.首先写一个MyAsyncTask类继承AsyncTask。
public class MyAsyncTask extends AsyncTask<String,Integer,Bitmap>{ @Override protected Bitmap doInBackground(String... params) { return null; } }
代码解析:这里我们注意到AsyncTask后面带的三个参数类型——Params:输入参数(请求参数,图片url等);Progress:进度(异步任务执行的过程);Result:结果(异步任务执行完成后返回的结果)。实现的doInBackground方法通常用来执行后台任务,其会在子线程中进行。0
2.几个重要的方法实现
——onPreExecute方法:执行异步任务之前的预处理,在主线程中执行
——onProgressUpdate:更新加载进度
——onPostExecute:异步任务完成后需要处理返回的结果
3.布局文件:TextView用于显示下载的进度百分比,ProgressBar就是下载的动态进度更新,ImageView显示下载的图片。
<TextView android:id="@+id/tv_progress" android:text="@string/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24sp"/> <ProgressBar android:id="@+id/pb" android:layout_width="match_parent" android:layout_height="wrap_content" style="@android:style/Widget.ProgressBar.Horizontal"/> <Button android:id="@+id/btn_download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始下载" android:textSize="20sp"/> <ImageView android:id="@+id/iv_image" android:layout_width="match_parentm" android:layout_height="match_parent" android:scaleType="center"/>
4.点击下载按钮我们要开启异步任务。这里传的url就是图片的地址。
MyAsyncTask myAsyncTask = new MyAsyncTask();myAsyncTask.execute(url);
5.在doInBackground方法中进行下载图片的相关操作。
@Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; try { //获取URL对象 URL url = new URL(params[0]); //打开连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //设置请求方式 connection.setRequestMethod("GET"); //设置连接超时 connection.setConnectTimeout(5000); if (connection.getResponseCode()==200){ //获取文件长度 maxLength = connection.getContentLength(); //设置进度条最大进度 progressBar.setMax(maxLength); //得到图片流 InputStream inputStream = connection.getInputStream(); bitmap = BitmapFactory.decodeStream(inputStream); } } catch (Exception e) { e.printStackTrace(); } return bitmap; }
6.在onPostExecute(Bitmap bitmap)方法中把异步任务处理的结果(图片)设置到ImageView上。
@Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); imageView.setImageBitmap(bitmap); }
7.记得加权限。
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
到这里其实已经可以把图片显示出来,但是加载进度条还没做。OK来做进度条。这里的做法是将图片下载到本地,再读取。
String fileName =imageUrl.substring(imageUrl.lastIndexOf("/")+1);FileOutputStream fileOutputStream = new FileOutputStream(SD_CARD_PATH+"/"+fileName);int len = 0;byte[] buffer = new byte[1024];while ((len = inputStream.read(buffer))!=-1){ fileOutputStream.write(buffer,0,len); //更新进度 publishProgress(len); }fileOutputStream.close();inputStream.close();bitmap=BitmapFactory.decodeFile(SD_CARD_PATH+"/"+fileName);
然后,我们在onProgressUpdate方法里面把加载进度text设上。
@Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); progressBar.setProgress(progressBar.getProgress()+values[0]); String text = "下载进度:"+100*progressBar.getProgress()/maxLength+"%"; progressTV.setText(text); }
大功告成。
- ANR,多线程,Handler,异步加载
- anr,多线程,handler
- 多线程与异步加载
- Android-Activity、Handler、ANR异常、多线程文件断点下载
- 多线程异步机制Handler以及AsyncTask
- 多线程编程之Handler异步消息处理
- 项目中用到的handler异步加载
- Android用Handler+Timer 异步加载
- Android:ListView数据异步加载、Handler、AsyncTask
- android异步加载之Handler、AsyncTask(一)
- 多线程第一步:资源异步加载
- C# 多线程 异步加载 窗体
- Cocos2dx多线程与异步加载
- 多线程异步加载图片async_pictures
- android异步的网络图片加载,支持多线程异步加载
- 3D引擎多线程:资源异步加载
- 使用NSoperation多线程异步加载图片数据
- 使用NSoperation多线程异步加载图片数据
- maven
- 字符串替换的一个工作实例
- vi命令大全
- LeetCode之Clone Graph
- LeetCode9:Palindrome Number
- ANR,多线程,Handler,异步加载
- node,core,CPU和GPU的关系
- 软件架构师应该知道的97件事之概括91-97
- 最大公约数与最小公倍数
- 面试题29:数组中出现次数超过一半的数字
- Git常用命令
- ARM_s5pv210_arm_1
- null unset
- UVa 1347 例题9-3 旅行 (双调欧几里得旅行商问题)