Java中多线程:
http://www.cnblogs.com/NeilZhang/p/6831636.html
开辟子线程,同时在子线程中发送消息,在主线程中处理消息。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler0 = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); doSomeThing(); } }; new myThread().start(); } public class myThread extends Thread{ @Override public void run() { super.run(); Looper.prepare(); Message mss = new Message(); mss.obj = "test in handler"; Log.d(TAG, "run: "+Thread.currentThread().getId()); handler0.sendMessage(mss); Looper.loop(); } }
另一种写法是:在MyThread中初始化handler0,增加 Looper.prepare() 和 Loop.loop();
public class myThread extends Thread{ @Override public void run() { super.run(); Looper.prepare(); handler0 = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d(TAG, "handleMessage: in myThread"+msg+" "+Thread.currentThread().getId()); } }; Message mss = new Message(); mss.obj = "test in handler"; Log.d(TAG, "run: "+Thread.currentThread().getId()); handler0.sendMessage(mss); Looper.loop(); } }
当 new MyThread().start(); 发送消息和处理消息都是在同一个进程中进行的。
这种方法似乎没有任何意义,实际应用不多。
进程1 发送消息给进程2 , 进程2 处理进程1发的消息,同时给 进程1 发送消息。
两个线程之间进行了通信。
class MyThread1 extends Thread { @Override public void run() { super.run(); Looper.prepare(); handler1 = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d(TAG,"threadName--" + Thread.currentThread().getId() + "messageWhat-"+ msg.what ); } }; try { sleep( 3000 ); } catch (InterruptedException e) { e.printStackTrace(); } handler2.sendEmptyMessage( 2 ) ; Log.d(TAG, "run: Mythread1 :"+Thread.currentThread().getId()); Looper.loop(); } } class MyThread2 extends Thread { @Override public void run() { super.run(); Looper.prepare(); handler2 = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d(TAG,"threadName--" + Thread.currentThread().getId() + "messageWhat-"+ msg.what ); } }; try { sleep( 4000 ); } catch (InterruptedException e) { e.printStackTrace(); } handler1.sendEmptyMessage( 5 ) ; Log.d(TAG, "run: Mythread2 :"+Thread.currentThread().getId()); Looper.loop(); } }
在程序中开启两个进程:
new MyThread1().start();
new MyThread2().start();
运行的结果:
总结:
1、调用Looper类的 prepare()
方法可以为当前线程创建一个消息循环,调用loop()
方法使之处理信息,直到循环结束。
2、Handler有几个构造重载,如果构造时不提供Looper类对象参数,会获取当前线程的Looper对象,即将当前线程的消息循环作为Handler关联的消息循环。
3、消息处理机制中,消息存放在一个消息队列中,而线程围绕这个队列进入一个无限循环,直到程序退出。
如果队列中有消息,线程就会把消息取出来,并分发给相应的Handler进行处理;
如果队列中没有消息,线程就会进入空闲等待状态,等待下一个消息的到来。
强化:主线程子线程中的通信
private void init3() { mTextView = (TextView) findViewById(R.id.text); Log.d(TAG, "init: "+Thread.currentThread().getId()); //1 子线程发送消息给本身 new Thread() { public void run() { long temp = Thread.currentThread().getId(); Log.d(TAG, "run: "+temp); Looper.prepare(); mHandlerTest1=new HandlerTest1(); Message message = new Message(); message.obj = "子线程发送的消息Hi~Hi"; mHandlerTest1.sendMessage(message); Looper.loop(); } }.start(); } private class HandlerTest1 extends Handler { private HandlerTest1(Looper looper) { super(looper); } private HandlerTest1(){ super(); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); System.out.println("子线程收到:" + msg.obj); Log.d(TAG, "handleMessage: in handlerTest1 : "+ Thread.currentThread().getId()); //2 收到消息后可再发消息到主线程 mHandlerTest2=new HandlerTest2(getMainLooper()); Message message = new Message(); message.obj = "O(∩_∩)O"; mHandlerTest2.sendMessage(message); } }
注意:
mHandlerTest2=new HandlerTest2(getMainLooper());
通过getMainLooper()函数获取主线程中的 消息队列,所以,
mHandlerTest2发送的消息都会发送到主线程中去。运行 Init3函数的结果为:
handlerTest2 在主线程中运行, handerler1在开辟的子线程中运行。
HandlerThread 用法:
private void init4(){ //创建一个线程,线程名字:handler-thread myHandlerThread = new HandlerThread( "handler-thread") ; //开启一个线程 myHandlerThread.start(); //在这个线程中创建一个handler对象 Log.d(TAG, "init4: "+Thread.currentThread().getId()); handler3 = new Handler( myHandlerThread.getLooper() ){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //这个方法是运行在 handler-thread 线程中的 ,可以执行耗时操作 Log.d(TAG , "消息: " + msg.what + " 线程: " + Thread.currentThread().getId() ) ; } }; //在主线程给handler发送消息 handler3.sendEmptyMessage( 1 ) ; new Thread(new Runnable() { @Override public void run() { Log.d(TAG, "new runnable "+Thread.currentThread().getId()); //在子线程给handler发送数据 handler3.sendEmptyMessage( 2 ) ; } }).start() ; }
- 在上述代码中,通过HandlerThread开启一个新的线程,将主线程中的Loop转到子线程中处理,降低了主线程的压力,
使主界面更流畅。 它有自己的MessageQueue不会干涉主线程中的消息队列。
- 程序中如果将此HandlerThread注释掉,程序会出错,因为它会在主线程中发消息给主线程去处理。
- 在HandlerThread内部消息,处理任务是串行执行,消息是顺序到达的。当队列中某个任务执行时间较长时,后续的任务就会被延迟处理。
上述程序的github地址为:(AndroidStudio项目)
git@github.com:lsfzlj/AndroidTestProject.git
后台开启线程的函数写法:
更加简洁明了:
public class BackTaskRunner { private static final String TAG = "BackTaskRunner"; private HandlerThread handlerThread; private Handler handler; private BackTaskRunner() { handlerThread = new HandlerThread(TAG); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } public static Handler getHandler() { return SingletonHolder.sRunner.handler; } private static class SingletonHolder { static BackTaskRunner sRunner = new BackTaskRunner(); } }
调用方法:
BackTaskRunner.getHandler().post(new Runnable() { @Override public void run() { Logging.d(TAG, "pay() start UNPay"); //最后一个参数: "01" 代表测试环境 "00" 代表正式环境 UPPayAssistEx.startPay(activity,null,null,tn,payMode); } });