************************************mHandler.postDelayed (图片轮询)和 mHandler.post(跟新UI)************************************
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.handlerdemo.MainActivity" > <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/tv" android:layout_marginRight="52dp" android:layout_marginTop="84dp" android:src="@drawable/ic_launcher" /> </RelativeLayout>
package com.example.handlerdemo; import android.R.mipmap; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity { private TextView tv; private Handler mHandler = new Handler(); private ImageView mImageView; private int images[] = {R.drawable.ic_launcher,R.drawable.ic_launcher1,R.drawable.ic_launcher2}; //图片位置 private int index; private MyRun myRun = new MyRun(); class MyRun implements Runnable{ @Override public void run() { index ++; index = index%3; mImageView.setImageResource(images[index]); /**在分线程中mHandler.post更新UI界面,1秒后handler再次循环发送Runnable对象*/ mHandler.postDelayed(myRun, 1000); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * Handler被绑定到主线程中,在分线程中mHandler.post更新UI界面, * handler可以分发Message对象和Runnable对象到主线程中 */ tv = (TextView) findViewById(R.id.tv); new Thread() { public void run() { mHandler.post(new Runnable() { @Override public void run() { tv.setText("xxx"); } }); }; }.start(); /** * 定时器作用,Handler被绑定到主线程中,在主线程中,1秒后handler直接发送Runnable对象 */ mImageView = (ImageView) findViewById(R.id.imageView); mHandler.postDelayed(myRun, 1000); } }
</pre><pre name="code" class="java">***************************************更新uI的5种方式********************************
布局文件只有一个textview
<pre name="code" class="java">package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView textView; private Handler handler = new Handler() { public void handleMessage(Message msg) { textView.setText("ok2"); Log.e("TAG", ""+msg.what);//1 }; }; /*** * 方法一 */ private void handler1() { handler.post(new Runnable() { @Override public void run() { textView.setText("ok1"); } }); } /** * 方法二 */ private void handler2() { handler.sendEmptyMessage(1); } /** * 方法三 */ private void updateUI(){ runOnUiThread(new Runnable() { @Override public void run() { textView.setText("ok3"); } }); } /** * 方法四 */ private void viewUpdateUi(){ textView.post(new Runnable() { @Override public void run() { textView.setText("ok4"); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); /** * 方法五 */ handler.post(new Runnable() { @Override public void run() { // TODO Auto-generated method stub textView.setText("ok5"); } }); new Thread() { public void run() { try { Thread.sleep(1000); // handler1(); // handler2(); // updateUI(); // viewUpdateUi(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } }
***********************************创建消息,发送消息各2种方式***************************************
Ui界面不变,复用上例的xml布局
MainActivity
package com.example.handlerdemo; import android.R.mipmap; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity { private TextView tv; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { tv.setText(""+msg.arg1+">>>"+msg.arg2+""+msg.obj); }; }; private ImageView mImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); mImageView = (ImageView) findViewById(R.id.imageView); new Thread() { public void run() { try { Thread.sleep(2000); Message message = mHandler.obtainMessage(); // Message message = new Message(); 或者可以用这个创建msg message.arg1 =88; message.arg2 =100; Person person = new Person(); person.age =10; person.name = "wyf"; message.obj = person; message.sendToTarget(); // mHandler.sendMessage(message); 或者可以用这个发送消息 } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } class Person{ public int age; public String name; @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } } }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.handlerdemo.MainActivity" > <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/tv" android:layout_marginRight="52dp" android:layout_marginTop="84dp" android:src="@drawable/ic_launcher" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imageView" android:layout_marginTop="32dp" android:layout_toLeftOf="@+id/imageView" android:text="Button" /> </RelativeLayout>
package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private TextView tv; private ImageView mImageView; private Button button; private Handler mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { Toast.makeText(MainActivity.this, "1", 0).show(); //这里为false,弹出1 2 如果为true,就只弹出1 return false; } }){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "2", 0).show(); } }; private int images[] = {R.drawable.ic_launcher,R.drawable.ic_launcher1,R.drawable.ic_launcher2}; //图片位置 private int index; private MyRun myRun = new MyRun(); class MyRun implements Runnable{ @Override public void run() { index ++; index = index%3; mImageView.setImageResource(images[index]); /**在分线程中mHandler.post更新UI界面,1秒后handler再次循环发送Runnable对象*/ mHandler.postDelayed(myRun, 1000); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); mImageView = (ImageView) findViewById(R.id.imageView); mHandler.postDelayed(myRun, 1000); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { //清空消息 mHandler.removeCallbacks(myRun); mHandler.sendEmptyMessage(1); } }
Looper内部包含一个MessageQueue
Looper.Looper死循环,不断的从MessageQueue取消息
并处理消息
Handler内部可以找到Looper,进而找到MessageQueue
进而在向MessageQueue队列发送消息
总结:
handler负责发送消息,Looper负责接收handler发送的消息
并直接把消息回传给handler自己
//ActivityThread负责创建所有的Activity
//创建Main线程
//ThreadLocal在线程中,set、get变量信息,比如Looper
//线程中有Looper
//创建一个MessageQuene
package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.widget.TextView; public class MainActivity extends Activity { private Handler UIHandler = new Handler() { public void handleMessage(Message msg) { Log.e("UI", "" + Thread.currentThread()); }; }; private MyThread myThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setText("hello"); setContentView(textView); myThread = new MyThread(); myThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 分线程handler发消息,在分线程执行 myThread.mHandler.sendEmptyMessage(1); // 主线程handler发消息,在主线程执行 UIHandler.sendEmptyMessage(1); } /** * 创建一个子线程,里面有个属性mHandler * */ class MyThread extends Thread { public Handler mHandler; @Override public void run() { super.run(); Looper.prepare(); mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.e("Thread", "" + Thread.currentThread()); } }; Looper.loop(); } } }
package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log; import android.widget.TextView; public class MainActivity extends Activity { private TextView textView; private HandlerThread thread; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); textView = new TextView(this); textView.setText("hello"); setContentView(textView); thread = new HandlerThread("handler thread"); thread.start(); handler = new Handler(thread.getLooper()){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.e("TAG", ""+Thread.currentThread()); } }; handler.sendEmptyMessage(1); } }
布局文件只有一个Button用来发送消息
package com.example.handlerdemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private Button sendButton; /** * 主线程的handler */ private Handler handler = new Handler() { public void handleMessage(Message msg) { Message message = new Message(); Log.e("TAG", "主线程"); //主线程收到消息后,向子线程发送消息 threadHandler.sendMessageDelayed(message, 1000); }; }; private Handler threadHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendButton = (Button) findViewById(R.id.send); sendButton.setOnClickListener(this); //HandlerThread是线程,这里是子线程的handler HandlerThread thread = new HandlerThread("handler stread"); thread.start(); threadHandler = new Handler(thread.getLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Message message = new Message(); // 子线程接受消息后,向主线程发送消息 handler.sendMessageDelayed(message, 1000); Log.e("TAG", "子线程"); } }; } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.send: handler.sendEmptyMessage(1); break; default: break; } } }
******************************************************