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>
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4889490.html,如需转载请自行联系原作者


相关文章
|
9天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
1月前
|
Python
如何在Python中实现线程之间的同步和通信?
【2月更文挑战第17天】【2月更文挑战第51篇】如何在Python中实现线程之间的同步和通信?
|
1月前
|
Java 调度 Android开发
构建高效Android应用:探究Kotlin多线程编程
【2月更文挑战第17天】 在现代移动开发领域,性能优化一直是开发者关注的焦点。特别是在Android平台上,合理利用多线程技术可以显著提升应用程序的响应性和用户体验。本文将深入探讨使用Kotlin进行Android多线程编程的策略与实践,旨在为开发者提供系统化的解决方案和性能提升技巧。我们将从基础概念入手,逐步介绍高级特性,并通过实际案例分析如何有效利用Kotlin协程、线程池以及异步任务处理机制来构建一个更加高效的Android应用。
35 4
|
1月前
|
API 数据库 Android开发
构建高效Android应用:探究Kotlin多线程优化策略
【2月更文挑战第14天】随着移动设备性能的日益强大,用户对应用程序的响应速度和流畅性要求越来越高。在Android开发中,合理利用多线程技术是提升应用性能的关键手段之一。Kotlin作为一种现代的编程语言,其协程特性为开发者提供了更为简洁高效的多线程处理方式。本文将深入探讨使用Kotlin进行Android多线程编程的最佳实践,包括协程的基本概念、优势以及在实际项目中的应用场景和性能优化技巧,旨在帮助开发者构建更加高效稳定的Android应用。
|
3月前
|
Java 调度 数据库
Android 性能优化: 如何进行多线程编程以提高应用性能?
Android 性能优化: 如何进行多线程编程以提高应用性能?
46 0
|
4月前
|
Java
线程间通信之Object.wait/notify实现
线程间通信之Object.wait/notify实现
28 0
|
4月前
|
消息中间件 存储 Unix
进程间通信和线程间通信总结
写在前面 面试的时候一定不要疲劳战,比如上午面了一个,然后中午不休息直接赶到另外一个相距比较远的公司,影响状态。 面试的时候一定不要紧张,不管对方有几个人,总之面试的时候做好充分准备,休息好,放松心态。 好了,言归正传,开始总结。
39 0
|
5天前
|
Java API 调度
安卓多线程和并发处理:提高应用效率
【4月更文挑战第13天】本文探讨了安卓应用中多线程和并发处理的优化方法,包括使用Thread、AsyncTask、Loader、IntentService、JobScheduler、WorkManager以及线程池。此外,还介绍了RxJava和Kotlin协程作为异步编程工具。理解并恰当运用这些技术能提升应用效率,避免UI卡顿,确保良好用户体验。随着安卓技术发展,更高级的异步处理工具将助力开发者构建高性能应用。
|
16天前
|
安全 Linux API
Android进程与线程
Android进程与线程
18 0
|
30天前
|
消息中间件 并行计算 网络协议
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
33 0