耗时操作ANR和handler

耗时操作
1.什么是ANR
在应用程序的主线程中执行一段耗时的代码, 就有可能出现ANR异常.
耗时的代码未执行结束时, 界面会卡住, 用户对界面进行了操作, 10秒之后耗时代码如果还未结束, 就会出现ANR异常
  * 2.怎么避免ANR
主线程中不要执行耗时的代码
如果一定要做耗时的事情, 开启新线程, 在新线程中执行
3.UI Thread
安卓手机中主线程负责刷新界面, 以及处理用户的操作
应用程序的界面都是由主线程创建的
界面的修改也只能在主线程中执行
 ** 4.Handler
有的时候我们需要执行一些耗时的代码, 会开启新线程, 这时又需要更新界面, 必须在主线程中操作, 那么就需要使用Handler来进行线程之间的通信
a.sendMessage():
新线程向主线程发送一个包含数据的消息, 主线程获取消息中的数据
在主线程中创建Handler子类对象, 重写handleMessage()方法
新线程中可以使用Handler的引用调用sendMessage()方法, 发送一个Message对象
只要执行了sendMessage()方法, 那么主线程会自动执行handleMessage()方法, 收到Message对象
b.post():
新线程向主线程发送一段代码, 主线程直接执行
在主线程中创建Handler对象
新线程中可以使用Handler调用post()方法发送一个Runnable对象

主线程会自动执行Runable的run()

运行结果图:


示例代码:

package com.oterman.myhandler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	TextView tv1=null;
	TextView tv2=null;
	int j;
	//sendmessage方式;
	Handler msgHandler=new Handler(){
		public void handleMessage(Message msg) {
			tv1.setText(msg.obj.toString());
			
		}
		
	};
	
	Handler postHandler=new Handler();//post方式
	
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        tv1=(TextView) findViewById(R.id.tv1);
        tv2=(TextView) findViewById(R.id.tv2);

    }
    //按钮一点击相应函数
    public void go1(View v){
    	tv1.setText("军哥好");
    	new Thread(new Runnable() {
			public void run() {
				for(int i=0;;i++){
					//采取发送消息的方式,将主线程要执行的代码封装成消息对象,然后send出去;
					Message msg=new Message();
					msg.obj=i;
					msgHandler.sendMessage(msg);
					
					SystemClock.sleep(1000);
				}
			}
		}){}.start();
    }
    //按钮2的点击响应函数,采用post方式提交要处理的消息给主线程;
    public void go2(View v){
    	tv2.setText("俊哥棒");
    	System.out.println("go:"+Thread.currentThread().getName());
    	new Thread(new Runnable() {
			public void run() {
				for(j=0;;j+=2){
					System.out.println("for:"+Thread.currentThread().getName());
					postHandler.post(new Runnable() {
						public void run() {//主线程要执行的代码;
							System.out.println("post_run:"+Thread.currentThread().getName());
							tv2.setText(j+"");
						}
					});
					SystemClock.sleep(1000);
				}
				
			}
		}){}.start();
    }


}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Handler 的工作原理是通过消息队列(Message Queue)和线程(Thread)来实现的。当我们使用 Handler 发送消息或者执行延迟任务时,其实是将消息或任务封装成 Message 对象,然后将其加入到消息队列中。然后,Handler 所在的线程会从消息队列中取出消息,并按照一定的逻辑进行处理。 在 Android 中,UI 线程(也称为主线程)是用来处理用户界面操作的,例如响应用户的点击事件、更新 UI 界面等。而 Handler 默认是与 UI 线程关联的,通过将消息发送到消息队列中,然后由 UI 线程处理,这样可以保证在 UI 线程中执行相关操作。 当 Handler 执行耗时操作时,如果没有采取适当的措施,可能会导致界面卡顿或 ANR(Application Not Responding)问题。为了避免这种情况发生,通常有以下几种方式: 1. 在主线程中避免执行耗时操作:将耗时操作放在子线程中执行,例如使用 AsyncTask、Thread 等方式。 2. 使用 Handlerpost 方法:通过 post 方法将耗时操作放在 Runnable 对象中,然后通过 Handler.post 方法将其发送到主线程中执行。 3. 使用 HandlerThread:HandlerThread 是一个带有 Looper 的线程,可以用于处理耗时操作,并且不会影响主线程的响应速度。 虽然 Handler 在处理消息时会阻塞线程,但由于它是与 UI 线程关联的,所以在主线程中阻塞一段时间并不会导致 ANR。但是,如果在主线程中执行耗时操作(如网络请求、数据库操作等),则会导致线程阻塞时间过长,从而触发 ANR。因此,在开发中需要注意避免在主线程中执行耗时操作,以保证应用的响应性和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值