Handler
1:handler
1:Handler对象在哪个线程中创建的,那么Handler就属于哪一个线程。
2:sendMessage方法哪一个Handler调用,就这个handler来处理消息。
处理消息。
1;handleMessage方法进行处理.创建Handler对象的时候进行重写。
2:post方法,传一个Runnable对象给post方法,那么Runnable的run方法就执行在调用post方法的handler对象所在的线程.
sendMessage,sendEmptyMessage,sendMessageAtTime底层都是调用sendMessageAtTime这个方法。
2:Ui线程跟work线程之间互相发送数据。
1:如果Handler在工作线程中创建,必须先调用Looper.prepare().创建完Handler对象后,调用Looper.loop().
(在ActivityThread类,底层已经帮我们已经调用以上的方法。)
3:Handler,Message的机制.
Looper.prepare()----创建Looper对象,去管理Messagequeue..
sendMessageAtTime()-----发消息----enqueueMessage()(将当前的handler对象设置给Message的target对象)---将消息放到Messagequeue里。
Looper.loop--有一个死循环,不断得从Messagequeue里取出消息---Message对象(msg)。------调用msg.target的dispatchMessage方法。------dispatchMessage方法里调用handler对象的handleMessage方法。
相关概念
Message Queue(消息队列):用来存放通过Handler发布的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列
Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息
Looper:是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理
Message:消息的类型,在Handler类中的handleMessage方法中得到单个的消息进行处理
* 下载图片
private ImageView image_main;
private Handler handler =new Handler() {
@Override
public void handleMessage(Message msg) {
//处理其他线程传递过来的消息。
Bitmap bitmap = (Bitmap) msg.obj;
image_main.setImageBitmap(bitmap);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image_main = (ImageView) findViewById(R.id.image_main);
//开启一个线程下载图片。
startThead();
}
private void startThead() {
new Thread(new Runnable() {
@Override
public void run() {
//执行在工作线程中。
String path = "http://img4.duitang.com/uploads/item/201306/20/20130620221932_FVnZK.thumb.600_0.jpeg";
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
;
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(is);
//将图片设置给ImageView.
//发送消息
Message msg = new Message();
//arg1,arg2--放的都是整数。 what---类型。也是整数。obj---放的是任意的对象
msg.obj = bitmap;
handler.sendMessage(msg);//发送消息。
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public class MainActivity extends AppCompatActivity {
private ImageView image_main;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image_main = (ImageView) findViewById(R.id.image_main);
//开启一个线程下载图片。
startThead();
}
private void startThead() {
new Thread(new Runnable() {
@Override
public void run() {
//执行在工作线程中。
String path = "http://img4.duitang.com/uploads/item/201306/20/20130620221932_FVnZK.thumb.600_0.jpeg";
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
;
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(is);
//显示图片。
handler.post(new Runnable() {
@Override
public void run() {
//工作在ui线程。
Log.i("Main",Thread.currentThread()+"");
image_main.setImageBitmap(bitmap);
}
});
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
广告轮播
private ViewPager vg_main;
private List<ImageView> list;
private int[] imags_id = {R.mipmap.a,R.mipmap.b,R.mipmap.c,R.mipmap.d,R.mipmap.e};
int position = 0;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//定位
vg_main.setCurrentItem(++position,true);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vg_main = (ViewPager) findViewById(R.id.viewpager);
initList();
MyPagerAdapter adapter = new MyPagerAdapter();
vg_main.setAdapter(adapter);
new Thread(new Runnable() {
@Override
public void run() {
//发送消息到主线程。
while(true) {
handler.sendEmptyMessage(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
private void initList() {
list = new ArrayList<ImageView>();
for(int i=0;i<imags_id.length;i++){
ImageView img = new ImageView(this);
img.setImageResource(imags_id[i]);
list.add(img);
}
}
class MyPagerAdapter extends PagerAdapter{
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(list.get(position%list.size()));
return list.get(position%list.size());
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(list.get(position%list.size()));
}
}
UI线程和工作线程互相传递
public class MainActivity extends AppCompatActivity {
private TextView tv_msg;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
String str = (String) msg.obj;
tv_msg.setText(str);
}
};
private Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
String str = (String) msg.obj;
tv_msg.setText(str);
Log.i("Main",str);
}
};
private Handler handler_work;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_msg = (TextView) findViewById(R.id.tv_message);
Button btn = null;
}
public void click(View view){
switch (view.getId()){
case R.id.btn_main:
//Ui线程向工作线程发送数据。
Message msg = handler_work.obtainMessage();
msg.obj = "我是main线程发送过来的消息";
handler_work.sendMessage(msg);
break;
case R.id.btn_workThread:
new Thread(new Runnable() {
@Override
public void run() {
Message msg = handler.obtainMessage();
msg.obj = "我是工作线程发送过来的消息";
handler.sendMessage(msg);
Message msg2 = handler2.obtainMessage();
msg2.obj = "我是工作线程发送过来的消息----2";
handler2.sendMessage(msg2);
//创建handler
Looper.prepare();
handler_work = new Handler(){
@Override
public void handleMessage(Message msg) {
String text = (String) msg.obj;
Log.i("work",text);
}
};
Looper.loop();//循环得取出消息。
}
}).start();
break;
}
}
}
倒计时
private Button btn_start;
private TextView tv_time,tv_stop;
private int total = 10;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//设置
int timer = msg.arg1;
tv_time.setText(msg.arg1 + "");
if(timer==0){
btn_start.setEnabled(true);
tv_stop.setVisibility(View.VISIBLE);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btn_start = (Button) findViewById(R.id.btn_start);
tv_time = (TextView) findViewById(R.id.tv_time);
tv_stop = (TextView) findViewById(R.id.tv_stop);
}
public void click(View view){
//按钮不再可用。
btn_start.setEnabled(false);
tv_stop.setVisibility(View.INVISIBLE);
//改变tv_time时间。
new Thread(new Runnable() {
@Override
public void run() {
int total = 10;
//马上设置。
Message msg = handler.obtainMessage();
msg.arg1 = total;
handler.sendMessage(msg);
for(int i=9;i>=0;i--){
Message msg2 = handler.obtainMessage();
msg2.arg1 = i;
handler.sendMessage(msg2);
Log.i("Main",msg2.arg1+"");
// 睡眠。
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现