zoukankan      html  css  js  c++  java
  • android 37 线程通信Looper


    安卓程序的主线程也叫UI线程。

    工作线程和主线程的差别:安卓主线程已经调用了Looper.prepare()方法了,已经有一个MessageQueue对象了,所以才可以在工作线程用Handler发消息到主线程:因为主线程有消息队列,发的消息都存在队列里面,并且主线程已经有Looper进行取消息了。
    自己创建的工作线程是没有MessageQueue和Looper,所以不能向工作线程发消息,因为没有存消息的地方和取消息的东西。但是他可以有MessageQueue和Looper。
    
    MessageQueue是消息队列,Looper轮训从消息队列中取消息,Handler用于发送和处理消息。

    mainActivity:

    package com.sxt.day06_02;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.os.SystemClock;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
        ProgressBar mProgressBar;
        TextView mtvProgress;
        
        static final int DOWNLOAD_START=0;
        static final int DOWNLOADING=1;
        static final int DOWNLOAD_FINISH=2;
        
        Handler mMainHanlder,mWokrThreadHanler;//主线程和工作线程的Handler,分别处理消息。
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initMainHandler();
            setListener();//下载按钮的监听器
            createWorkThread();
        }
    
        private void createWorkThread() {
            new Thread(){//工作线程
                public void run() {//Looper和mWokrThreadHanler都是在工作线程创建
                    Looper.prepare();//创建Looper对象和工作线程中的MessageQueue
                    mWokrThreadHanler=new Handler(){
                        public void handleMessage(Message msg) {
                            if(msg.what==DOWNLOAD_START){
                                Log.i("main","work thread start downlad");
                                for(int i=1;i<=100;i++){
                                    SystemClock.sleep(20);
                                    Message msg2 = Message.obtain();
                                    msg2.what=DOWNLOADING;
                                    msg2.arg1=i;
                                    mMainHanlder.sendMessage(msg2);//发送到主线程的消息队列,然后主线程的Looper从主线程消息队列取出来,调用mMainHanlder处理
                                    mProgressBar.setProgress(i);
                                }
                                //循环结束后发送完成消息
                                Message msg2 = Message.obtain();
                                msg2.what=DOWNLOAD_FINISH;
                                mMainHanlder.sendMessage(msg2);//发送到主线程
                            }
                        };
                    };
                    Looper.loop();//轮询MessageQueue,取到消息后交给mWokrThreadHanler的handleMessage()方法进行处理(上面的方法),
                };
            }.start();
        }
    
        private void setListener() {
            findViewById(R.id.btnStartDownload).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    //工作线程Handler向自己工作线程发送消息,发送至工作线程的消息队列MessageQueue中,空消息通知工作线程开始下载
                    mWokrThreadHanler.sendEmptyMessage(DOWNLOAD_START);
                }
            });
        }
    
        private void initMainHandler() {
            mMainHanlder=new Handler(){//在主线程new,所以为主线程服务
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                    case DOWNLOADING:
                        mtvProgress.setText(msg.arg1+"%");
                        break;
                    case DOWNLOAD_FINISH:
                        Toast.makeText(MainActivity.this, "下载完成", 2000).show();
                        break;
                    }
                }
            };
        }
    
        private void initView() {
            mProgressBar=(ProgressBar) findViewById(R.id.pb);
            mtvProgress=(TextView) findViewById(R.id.tvProgress);
        }
    }

    页面:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btnStartDownload"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="开始下载" />
        <ProgressBar
            android:id="@+id/pb"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:max="100"/>
        <TextView 
            android:id="@+id/tvProgress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="0%"/>
    </LinearLayout>
  • 相关阅读:
    JS基础算法题(一)
    JS数组的迭代器方法
    使用IcoMoon制作字体图标
    CSS浮动属性
    使用hibnate向数据库写入图片对象
    hibernate_基本配置和初始化步骤
    ORM框架
    Jsp中的session
    mysql的自我复制
    分页技术
  • 原文地址:https://www.cnblogs.com/yaowen/p/4889490.html
Copyright © 2011-2022 走看看