一、耗时操作
1.什么是ANR
在应用程序的主线程中执行一段耗时的代码, 就有可能出现ANR异常.
耗时的代码未执行结束时, 界面会卡住, 用户对界面进行了操作, 10秒之后耗时代码如果还未结束, 就会出现ANR异常
2.怎么避免ANR
主线程中不要执行耗时的代码
如果一定要做耗时的事情, 开启新线程, 在新线程中执行
3.UI Thread
安卓手机中主线程负责刷新界面, 以及处理用户的操作
应用程序的界面都是由主线程创建的
界面的修改也只能在主线程中执行
4.Handler
有的时候我们需要执行一些耗时的代码, 会开启新线程, 这时又需要更新界面, 必须在主线程中操作, 那么就需要使用Handler来进行线程之间的通信
1)sendMessage():
新线程向主线程发送一个包含数据的消息, 主线程获取消息中的数据
在主线程中创建Handler子类对象, 重写handleMessage()方法
新线程中可以使用Handler的引用调用sendMessage()方法, 发送一个Message对象
只要执行了sendMessage()方法, 那么主线程会自动执行handleMessage()方法, 收到Message对象
2)post():
新线程向主线程发送一段代码, 主线程直接执行
在主线程中创建Handler对象
新线程中可以使用Handler调用post()方法发送一个Runnable对象
主线程会自动执行Runable的run()
5.示例代码
sendMessage:
package com.gnnuit.anr; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.TextView; public class SendMessageActivity extends Activity { private TextView tv; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) {// 该方法在sendMessage()方法之后执行, 形参就是发送过来的Message对象 tv.setText(msg.obj + "");// 主线程更新界面 }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void go(View v) { new Thread() { public void run() { for (int i = 1; i < 10; i++) { System.out.println(i + ""); SystemClock.sleep(1000); // Message msg = new Message(); // 创建消息对象,此种方法效率不高 Message msg = handler.obtainMessage(); // 从消息池中获取一个Message msg.obj = i;// 把数据放在消息对象中 handler.sendMessage(msg);// 在新线程中发送消息对象, 主线程会自动执行handleMessage()方法 } }; }.start(); } }
post:
package com.gnnuit.anr; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.TextView; public class PostActivity extends Activity { private TextView tv; private Handler handler = new Handler(); private int i; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void go(View v) { System.out.println("go:" + Thread.currentThread().getName() + ""); new Thread() { public void run() { System.out.println("for:" + Thread.currentThread().getName() + ""); for (i = 1;; i++) { System.out.println(i + ""); handler.post(new Runnable() {// 在新线程中使用Handler向主线程发送一段代码, 主线程自动执行run()方法 @Override public void run() { System.out.println("run:" + Thread.currentThread().getName() + ""); tv.setText(i + ""); } }); SystemClock.sleep(1000); } }; }.start(); } }
Android总结四(Handler),布布扣,bubuko.com
原文:http://www.cnblogs.com/FlySheep/p/3841190.html