android handler

本文介绍了Android中使用Handler进行UI更新的方法。包括在主线程和新线程中使用Handler的不同方式,通过示例代码展示了如何避免ANR问题,并保持UI的实时更新。

android提供了handler来处理UI更新的问题

handler有2种处理方式

1.跟主线程在同以线程,可以实现UI更新,但是操作不当也会有ANR问题

2.跟主线程不在同一个线程,新起一个线程。在新的线程中耗时的操作不会有ANR问题

具体代码如下:

package com.stmars.handler;

import com.studymar.radiocheckbox.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class TestHandler extends Activity {
	// 1.声明控件变量
	ProgressBar downBar = null;
	Button sureButton = null;
	Button cancleButton = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.progressxml);
		// 2.获取控件对象
		initElem();
		// 3.设置button监听
		//setlistener();
		 testnewthread();
		Log.i("123", "main thread id=" + Thread.currentThread().getId());
	}

	private void testnewthread() {
		HandlerThread prHandlerThread = new HandlerThread("handlerthread") {
			// 新的线程,耗时操作可以放在里面
			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
			}

		};
		prHandlerThread.start();
		Handler qqHandler = new Handler(prHandlerThread.getLooper()) {
			int i = 0;

			public void handleMessage(Message msg) {
				Log.i("123", "handler thread id="
						+ Thread.currentThread().getId());
				if (i <= 100)
					downBar.setProgress(i);
				else {
					i = 0;
				}
				i = i + 10;
				// progressHandler.sendMessage(msg);
				this.sendEmptyMessage(0);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			};
		};
		Message msg = qqHandler.obtainMessage();
		msg.sendToTarget();

	}

	class MyHandler extends Handler {
		public MyHandler() {

		}

		public MyHandler(Looper mylooper) {
			super(mylooper);
		}

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
		}

	}

	Handler progressHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			progressHandler.post(r);
		}
	};

	Runnable r = new Runnable() {
		int i = 0;

		@Override
		public void run() {
			// Message msg=progressHandler.obtainMessage();
			if (i <= 100)
				downBar.setProgress(i);
			else {
				i = 0;
			}
			i = i + 10;

			// progressHandler.sendMessage(msg);
			progressHandler.sendEmptyMessage(0);
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	};

	private void setlistener() {
		sureButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 4.进度条开始前进
				progressHandler.post(r);
			}
		});
		cancleButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 5.进度条结束
				progressHandler.removeCallbacks(r);
			}
		});
	}

	private void initElem() {
		downBar = (ProgressBar) findViewById(R.id.download);
		sureButton = (Button) findViewById(R.id.sure);
		cancleButton = (Button) findViewById(R.id.cancle);
		downBar.setMax(100);
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}
}


### Android Handler 使用与常见问题 在 Android 开发中,`Handler` 是用于在不同线程之间通信的重要工具。它主要用于将任务(如 UI 更新)从后台线程传递到主线程执行,从而避免主线程阻塞并确保 UI 的流畅性。 #### Handler 的基本使用 `Handler` 通常与 `Looper` 和 `MessageQueue` 配合使用。每个 `Handler` 实例都与一个线程及其消息队列相关联。通过 `Handler`,可以发送和处理消息(`Message`)或运行 `Runnable` 对象。 以下是一个简单的 `Handler` 示例: ```java Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { // 更新 UI 的代码 } }); ``` 在子线程中使用 `Handler` 时,需要确保该线程已经调用了 `Looper.prepare()` 并启动了 `Looper.loop()`,否则会抛出异常。 #### 常见问题 1. **内存泄漏** 如果 `Handler` 持有对 `Activity` 或 `Context` 的引用,并且在子线程中长时间运行,可能会导致内存泄漏。为避免这种情况,通常建议使用静态内部类或弱引用(`WeakReference`)来持有外部类的引用。 ```java private static class MyHandler extends Handler { private final WeakReference<Activity> mActivityReference; public MyHandler(Activity activity) { mActivityReference = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { Activity activity = mActivityReference.get(); if (activity != null) { // 处理消息 } } } ``` 2. **消息延迟与顺序问题** 使用 `sendMessageDelayed()` 或 `postDelayed()` 可以实现延迟执行任务的功能。然而,如果多次发送相同的消息或 `Runnable`,可能会导致消息堆积,影响程序的响应速度。为避免此类问题,可以使用 `removeCallbacks()` 或 `removeMessages()` 来清理不再需要的消息。 3. **线程安全问题** 虽然 `Handler` 本身是线程安全的,但如果多个线程同时操作共享的数据结构,仍然需要额外的同步机制。例如,使用 `synchronized` 关键字或 `ReentrantLock` 来确保数据的一致性。 4. **主线程阻塞** 如果在 `Handler` 中执行耗时操作,可能会阻塞主线程,导致 ANR(Application Not Responding)错误。应避免在 `Handler` 中执行网络请求、数据库查询等耗时任务,建议使用 `AsyncTask`、`Thread` 或 `ExecutorService` 来处理这些操作。 5. **Looper 未初始化** 在非主线程中使用 `Handler` 时,必须手动调用 `Looper.prepare()` 来创建 `MessageQueue`,并在最后调用 `Looper.loop()` 来开始处理消息。如果忘记调用这些方法,会导致运行时异常。 ```java new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Handler handler = new Handler(); Looper.loop(); } }).start(); ``` 6. **消息优先级** 默认情况下,所有消息的优先级相同。如果需要处理高优先级的任务,可以通过 `Message` 的 `setAsynchronous()` 方法来标记异步消息,但这需要底层支持(如 `ViewRootImpl` 的 `Choreographer`)。 #### 总结 `Handler` 是 Android 中实现线程间通信的核心机制之一,但其使用过程中需要注意内存管理、线程安全、消息顺序等问题。合理使用 `Handler` 可以提升应用的响应能力和用户体验。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值