Android学习--handler和handlerThread

来源:互联网 发布:苹果平板淘宝不能横屏 编辑:程序博客网 时间:2024/05/16 18:11

机制要点:

每个Handler的实例都关联了一个线程和线程的消息队列。当创建了一个Handler对象时,一个线程或消息队列同时也被创建,该Handler对象将发送和处理这些消息或Runnable对象。采用默认构造函数意味着自动与主线程关联,系统为主线程自动创建了Looper,MessageQueue。那么简而言之,handler的作用是将消息发送给关联的线程,在关联线程中运行关联线程的run方法,因此如果handler和主线程关联了,那么自然可以更新主线程的UI了啊~~~~

常见更新UI的方法:

1、runOnUiThread

2、handle post 

利用runnable执行时,相当于直接调用runnable中的run方法,可以不启动线程。


3、handle sendMessage 

3.1在主线程中声明创建handler,并且重写handleMessage方法

3.2在子线程中声明线程,run方法中利用handler调用sendMessage方法

3.3在主线程中启动子线程,调用start方法


4、view post


方法:

1.post/postDelayed

2.sendMessage

public class MainActivity extends Activity {//private MyThread thread;private Handler handler=new Handler()//默认构造函数与主线程关联{public void handleMessage(Message msg)//主线程处理消息{//Toast.makeText(getApplicationContext(), ""+2, 1).show();tv.setText("继承Thread的线程结合handler");}};private MyRunnable myRunnable;private TextView tv;private int index=0;class MyRunnable implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stubindex++;tv.setText(index+"");Log.i("tv",tv.getText().toString());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}handler.postDelayed(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubtv.setText("运行一次");}},1000);}}class MyThread extends Thread{@Overridepublic void run() {// TODO Auto-generated method stub//super.run();handler.sendEmptyMessage(1);//子线程中发送消息};//}}//Thread类结束*/    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv=(TextView)findViewById(R.id.tv);                //开启了两个线程,分别使用的是runnable+handler+post,thread+handler+sendMessage方法,其实都可以互换的,本质是Thread + handler +post/sendMessage        myRunnable =new MyRunnable();        Thread thread=new Thread(myRunnable);        thread.start();                MyThread my=new MyThread();        my.start();     }    @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;    }    }
注意:如果改变postDelayed语句中的Runnable对象,那么会反复调用myRunnable中的run方法,不断用handler修改UI线程

private MyRunnable myRunnable;private TextView tv;private int index=0;class MyRunnable implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stubindex++;tv.setText(index+"");Log.i("tv",tv.getText().toString());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}handler.postDelayed(myRunnable,1000);}}

注意:直接利用handler对象post了一个runnable对象,相当于直接调用了Runnable对象的run函数,也就说没有经过start函数调用run(),那么就不会创建一个新线程,而是在原有线程内部直接调用 run()方法,打印子线程ID和主线程ID会发现是相同的。

public class MainActivity extends Activity {private Handler handler=new Handler(/*thread.looper*/){public void handleMessage(Message msg){//Toast.makeText(getApplicationContext(), ""+2, 1).show();tv.setText("runnable构造的线程结合handler");}};private MyRunnable myRunnable;private TextView tv;private int index=0;class MyRunnable implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stubindex++;tv.setText(index+"");Log.i("tv",tv.getText().toString());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}handler.postDelayed(myRunnable,1000);//反复调用myRunnable的run方法}}    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv=(TextView)findViewById(R.id.tv);                        myRunnable =new MyRunnable();//没有调用runnable的start方法照样可以运行相同效果        handler.post(myRunnable);    }    @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;    }    }
注意:希望new一个带参构造函数的Handler对象,那么这个Handler对象将与参数所表示的Looper相关联。注意:此时线程类应该是一个特殊类HandlerThread类,它继承自Thread类。

HandlerThread的使用1

  HandlerThread my=new HandlerThread("MyThread"); //构造方法中必须有string name       my.start();//启动线程
      //利用子线程的looper构造与本线程相关联的handler       Handler myHandler=new Handler(my.getLooper()){       @Override    public void handleMessage(Message msg) {    // TODO Auto-generated method stub    super.handleMessage(msg);     Log.i("my", "MyHandler-->handleMessage-->threadid = " + Thread.currentThread().getName());    }       };          myHandler.sendEmptyMessage(1);//向子线程发送

子线程和主线程的交互

public class FromMainThread extends Activity implements OnClickListener {private Handler handler =new Handler(){public void handleMessage(Message msg){System.out.println("main handler");Message msg2=new Message();//主线程向子线程发送消息threadHandler.sendMessageDelayed(msg2, 1000);}};private Handler threadHandler;private Button but1;private Button but2;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.frommainthread);HandlerThread thread=new HandlerThread("my");thread.start();threadHandler=new Handler(thread.getLooper()){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stub//super.handleMessage(msg);System.out.println("threadhandler");Message msg1=new Message();//子线程向主线程发送消息handler.sendMessageDelayed(msg1, 1000);//主线程的handler}};but1=(Button)findViewById(R.id.button1);but2=(Button)findViewById(R.id.button2);but1.setOnClickListener(this);but2.setOnClickListener(this);}@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubswitch(arg0.getId()){case(R.id.button1):handler.sendEmptyMessage(1);break;case(R.id.button2):handler.removeMessages(1);break;}}}

总结:handler采用默认构造函数则表示与主线程关联,否则采用handlerThread的getLooper进行初始化,与该子线程关联。调用handler发送消息,就在构造handler的线程中运行handleMessage



0 0
原创粉丝点击