案例1:子线程改变主线程控件
package com.example.myhandler;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
tv = (TextView) findViewById(R.id.tv);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
int count=0;
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what==0x1012){
tv.setText("Handler接收到了消息改变了TextView控件"+count++);
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<100;i++){
handler.sendEmptyMessage(0x1012);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
break;
}
}
}
案例2:倒计时条
package com.example.myhandler;
public class MainActivity2 extends AppCompatActivity{
private ProgressBar pb;
private int time=10;//定义总时长
private int mProgress = 0;//定义完成的进度
final int TIMER_MSG=0x001;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
initView();
}
Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(time-mProgress >=0){
//更新进度条
mProgress++;
pb.setProgress(time-mProgress);
handler.sendEmptyMessageDelayed(TIMER_MSG,1000 );
}else {
Toast.makeText(MainActivity2.this, "时间到!", Toast.LENGTH_SHORT).show();
}
}
};
private void initView() {
pb = (ProgressBar) findViewById(R.id.pb);
handler.sendEmptyMessage(TIMER_MSG);//启动进度条
}
}
Message对象
创建Message对象,推荐使用以下方法避免分配过多的新对象,增加内存消耗
方法1:Message msg=Message.obtain();
方法2:Message msg=handler.obtainMessage();
如果消息只需要携带int型信息,优先使用Message的arg1和arg2属性
发消息的时候多使用Message.what来标识信息,方便处理信息
演示
Message message=handler.obtainMessage();
Bundle bundle=new Bundle();
bundle.putString("message","Handler接收到了消息改变了TextView控件"+count++);
message.obj=bundle;
message.what=0x1012;
handler.sendMessage(message);
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what==0x1012){
//对比消息是否匹配
//Handler接收到了消息
Bundle bundle= (Bundle) msg.obj;
tv.setText(bundle.getString("message"));
}
}
};
案例3:轮播图
package com.example.myhandler;
public class MainActivity3 extends AppCompatActivity {
private ViewFlipper vf;
private int img[]={
R.drawable.drink1,R.drawable.drink2,R.drawable.drink3,R.drawable.drink4,R.drawable.drink5,R.drawable.drink6};
private Animation animation[]=new Animation[2];
private final int FLAGE_MSG=0x001;
private Message message;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_3);
initView();
}
private void initView() {
vf = (ViewFlipper) findViewById(R.id.vf);
//获取图片对象
for(int i=0;i<img.length;i++){
ImageView imageView=new ImageView(this);
imageView.setImageResource(img[i]);
vf.addView(imageView);
}
//创建动画
animation[0]= AnimationUtils.loadAnimation(this,R.anim.slide_in_right);
animation[1]= AnimationUtils.loadAnimation(this,R.anim.slide_out_left);
vf.setInAnimation(animation[0]);
vf.setOutAnimation(animation[1]);
//开启轮播
message=Message.obtain();
message.what=FLAGE_MSG;
handler.sendMessage(message);
}
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what==FLAGE_MSG){
vf.showPrevious();//切换到下一章图片
message=handler.obtainMessage(FLAGE_MSG);//获取message
handler.sendMessageDelayed(message,3000);
}
}
};
}
Looper对象
Handler在主线程中创建,系统自动创建Looper对象。
如果想在子线程中使用Handler那么需要手动创建Looper对象
创建的步骤
package com.example.myhandler;
import androidx.annotation.NonNull;
public class LooperThread implements Runnable {
public Handler handler;
@Override
public void run() {
Looper.prepare();//出书画Looper对象
handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.i("Looper","2017.10.12");
}
};
Message message=handler.obtainMessage();//获取Message对象
message.what=0x0602;//设置消息代码
handler.sendMessage(message);//发送消息
Looper.loop();//开启Looper
}
}
子线程中直接执行更改界面
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show();
}
});