一、线程
继承Thread类
实现Runnable接口
二、Handler机制
主线程有一个消息队列(对于我们不可见);
我们只需要考虑如何存放消息(子线程放进去)和处理消息(将消息拿出来)。
Handler:
1、发送一个Mesaage对象
2、处理一个Message
Message:
传递信息
子线程创建一个Message对象,设置需要界面的信息
通过Handler发送
(系统自动调用)Handler的处理消息方法
存放消息:
sendMessage(Message) 已经实现
只需要关注需要Handler处理的内容是什么
多个子线程,Handler如何区分是哪一个子线程的消息?——msg.what = 0可以标识具体是哪个线程。
处理消息:
handleMessage 需要自己重写
三、实现最简单的改变页面的文字
需求:页面的文字TextView为i,每秒将i+1。
首先,新建一个handler,使用消息机制,在处理消息的时候,根据得到的消息数值,改变TextView;
接着,需要设置线程,根据Thread.sleep(1000),得到每秒增加1;
最后,在主函数中启动线程。
1、页面的文字id
activity_main.xml中得到,TextView的id:counter
android:id="@+id/counter"
2、消息机制handler类:HandlerCounter,需要传入TextView对象
重写处理message方法,在该方法内将得到msg的obj后,将TextView值变为obj的值。
package com.example.iris.run;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
/**
* HandlerCount继承了Handler,为本项目的消息机制,使用其来传递子线程的消息到主线程
*/
public class HandlerCount extends Handler {
//使用构造方法,在主函数中创建HandlerCount对象的时候,将需要改变的文字对象textView传入
private TextView textView;
public HandlerCount(TextView textView){
this.textView=textView;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//获取msg.obj传入的对象
String s = (String)msg.obj;
//改变textView的值,使得其在主页面改变
textView.setText(s);
}
}
3、线程:Couter,实现Runnable接口,创建需要传入Handler,用于消息的创建和发送
package com.example.iris.run;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* Counter类实现了Runnable接口,用于根据时间1s,计数。
*/
public class Counter implements Runnable {
//构造方法,在创建Counter线程对象的时候,将我们创建的Handler对象传入,用于发送消息
Handler handler ;
public Counter(Handler handler){
super();
this.handler = handler;
}
//重写run方法,用于每秒计数、计数后发送消息
@Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 界面显示内容 Logcat内显示
Log.i("run", "" + i);
// 1、创建消息对象:两种方式
// (1)创建新的Message对象;比较占用内存
//Message msg = new Message();
// (2)从message全局池里取出一个新的message;不太占用内存,可以避免重复创建Message对象
Message msg = handler.obtainMessage();
// 2、定义消息对象msg的内容:i
msg.obj = i+"";
//3、使用传入的handler发送消息
handler.sendMessage(msg);
}
}
}
4、主方法:代码写在onCreat()中
1、获取组件对象
2、创建HandlerCounter消息机制时,将组件对象传入
3、创建线程counter的时候,将HandlerCounter对象传入
4、启动线程
package com.example.iris.run;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 一、找出组件textShowCounter
TextView textShowCounter = (TextView)this.findViewById(R.id.counter);
// 二、创建handler,传textShowCounter进去,用于在处理消息的时候更改textShowCounter的值
HandlerCount handlerCount = new HandlerCount(textShowCounter);
// 三、创建线程的时候将handlerCount传入线程Counter类,
Counter c = new Counter(handlerCount);
// 四、启动线程每秒更新msg的值,并传入消息机制handler
new Thread(c).start();
}
}
5、结果: