安卓中多线程

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();
        }
    }
View Code

当 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();
        }
    }
View Code

在程序中开启两个进程:

  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);
        }
    }
View Code

注意:

  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() ;
    }
View Code

                                    

  •   在上述代码中,通过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);
            }
        });
原文地址:https://www.cnblogs.com/NeilZhang/p/7078930.html