在主线程里不能有耗时的操作,比如访问网络,否则容易造成线程阻塞。
Android4.0之后联网一定要在子线程中进行。IO若是文件比较大,也应当放入子线程,还有查询数据库(当数量十分多时),耗时多的算法。
ANR(Application/Activity Not Response) ,若是在等待的过程中乱点,便会造成此问题。
子线程不能修改UI,修改UI必须在主线程,主线程又叫做UI线程。
同样,子线程里不能出现 Toast 等。
所以只能子线程发送消息,主线程处理消息。
Handler对象所在线程属于创建它的线程。
①在主线程创建一个Handler对象
②在子线程需要更新的地方,通过handler发送信息
2.1直接new Message
2.2如果有数据需要传输,则通过message obj来携带
2.3通过handler的sendMessage方法,发送消息。
③在handlerMessage方法中接受消息,更新界面。
Handler原理:
ActivityThread 它有 main 方法
preMainLooper() ->创建一个Looper,并且把这个Looper跟当前的线程绑定在一起,又创建了一个消息队列(MessageQueue)
①Looper 轮询器,消息放在消息队列里,也称消息泵,一个Looper对应一个MessageQueue,取出了消息,就调用handleMessage方法处理消息。
②MessageQueue 消息队列,只记住了消息中的第一条,每个都有next指向下一条,管理消息,对消息进行排序(按执行消息时间排序)。
③Handler 一new出来,就对应子线程的Looper , 发送消息,sendMessageAtTime(Message msg,long time);
④Message消息 创建一个消息,发送一个消息,就相当于把消息放入消息队列中 , 按照执行的时间(每个message都有一个when)放入一个合适的位置(越早越靠前)。若是message等到了执行的时间,便把消息丢给Handler处理。Message用完后有重用机制,可以调用obtain() 方法,节约系统资源。
handler作用:
消息从子线程传到主线程,
控制消息被执行的时间,可以用来做计时器,比如音乐播放器,更新显示的时间.
sendMessageDelayed(Message msg,long time) ; sendEmptyMessageDelayed(int what,long time);
public class MainActivity extends Activity {
private TextView tv;
private int count=60;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
count--;
tv.setText(count+"");
Message mesg=new Message();
handler.sendMessageDelayed(mesg,1000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
handler.sendEmptyMessageDelayed(1, 1000);
}
}