`

android的多线程如何通信

 
阅读更多

 参考:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=49595&highlight=handler

            http://blog.csdn.net/itachi85/article/details/8035333

 

Android提供了Handler和Looper来满足线程间的通信。

Handler是消息的处理者,可以发布或者处理或者操作一个Runnable, handler接受消息后调用handleMessage进行处理。

Looper是Handler与消息队列之间通讯桥梁,程序组件通过Handler把消息传递给Looper,Looper把消息放入队列。

 

一、几个关键概念

1、MessageQueue:是一种数据结构,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个MessageQueue。其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare()函数来实现。

2、Message:消息对象,MessageQueue中存放的对象。一个MessageQueue中包含多个Message。
Message实例对象的取得,通常使用Message类里的静态方法obtainMessage(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先从MessagePool(消息池)中看有没有可用的Message实例,若存在则直接取出返回这个实例。如果MessagePool中没有可用的Message实例,则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从MessageQueue中删除,同时放入到MessagePool中。除了上面这种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。


3、Looper:
是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare()函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象。
创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以不能接收Message。如需要接收,自己定义一个Looper对象(通过prepare()函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入MessagePool中。

4、Handler:
消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;将消息传递给Looper,这时通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法对其进行处理。

 

二、线程之间的消息如何进行传递

 

1、主线程给自己发送Message

 

public class MainActivity extends Activity {
    
    private Button btnTest;
    private TextView textView;
    
    private Handler handler;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnTest = (Button)this.findViewById(R.id.btn_01);
        textView = (TextView)this.findViewById(R.id.view_01);
        
        btnTest.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                
                Looper looper = Looper.getMainLooper(); //主线程的Looper对象
                //这里以主线程的Looper对象创建了handler,
                //所以,这个handler发送的Message会被传递给主线程的MessageQueue。
                handler = new MyHandler(looper);
                handler.removeMessages(0);
                //构建Message对象
                //第一个参数:是自己指定的message代号,方便在handler选择性地接收
                //第二三个参数没有什么意义
                //第四个参数需要封装的对象
                Message msg = handler.obtainMessage(1,1,1,"主线程发消息了");
                
                handler.sendMessage(msg); //发送消息
                
            }
        });
    }
    
    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
        }
    }
}

 

2、其他线程给主线程发送Message

 

public class MainActivity extends Activity {
    
    private Button btnTest;
    private TextView textView;
    
    private Handler handler;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnTest = (Button)this.findViewById(R.id.btn_01);
        textView = (TextView)this.findViewById(R.id.view_01);
        
        btnTest.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                
                //可以看出这里启动了一个线程来操作消息的封装和发送的工作
                //这样原来主线程的发送就变成了其他线程的发送,简单吧?呵呵
                new MyThread().start();    
            }
        });
    }
    
    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
        }
    }
    
    //加了一个线程类
    class MyThread extends Thread{
        
        public void run(){
            Looper looper = Looper.getMainLooper(); //主线程的Looper对象
            //这里以主线程的Looper对象创建了handler,
            //所以,这个handler发送的Message会被传递给主线程的MessageQueue。
            handler = new MyHandler(looper);

            //构建Message对象
            //第一个参数:是自己指定的message代号,方便在handler选择性地接收
            //第二三个参数没有什么意义
            //第四个参数需要封装的对象
            Message msg = handler.obtainMessage(1,1,1,"其他线程发消息了");
            
            handler.sendMessage(msg); //发送消息            
        }
    }
}

 

3、主线程给其他线程发送Message

 

public class MainActivity extends Activity {
    
    private Button btnTest;
    private TextView textView;
    
    private Handler handler;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnTest = (Button)this.findViewById(R.id.btn_01);
        textView = (TextView)this.findViewById(R.id.view_01);
        
        
        //启动线程
        new MyThread().start();    
        
        btnTest.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                //这里handler的实例化在线程中
                //线程启动的时候就已经实例化了
                Message msg = handler.obtainMessage(1,1,1,"主线程发送的消息");
                handler.sendMessage(msg);
            }
        });
    }
    
    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
        }
    }
    
    class MyThread extends Thread{
        
        public void run(){
            Looper.prepare(); //创建该线程的Looper对象,用于接收消息
            
            //注意了:这里的handler是定义在主线程中的哦,呵呵,
            //前面看到直接使用了handler对象,是不是在找,在什么地方实例化的呢?
            //现在看到了吧???呵呵,开始的时候实例化不了,因为该线程的Looper对象
            //还不存在呢。现在可以实例化了
            //这里Looper.myLooper()获得的就是该线程的Looper对象了
            handler = new ThreadHandler(Looper.myLooper());
            
            //这个方法,有疑惑吗?
            //其实就是一个循环,循环从MessageQueue中取消息。
            //不经常去看看,你怎么知道你有新消息呢???
            Looper.loop(); 

        }
        
        //定义线程类中的消息处理类
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            public void handleMessage(Message msg){
                //这里对该线程中的MessageQueue中的Message进行处理
                //这里我们再返回给主线程一个消息
                handler = new MyHandler(Looper.getMainLooper());
                
                Message msg2 = handler.obtainMessage(1,1,1,"子线程收到:"+(String)msg.obj);
                
                handler.sendMessage(msg2);
            }
        }
    }
}

 

4、其他线程给自己发送Message 

 

public class MainActivity extends Activity {
    
    private Button btnTest;
    private TextView textView;
    
    private Handler handler;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnTest = (Button)this.findViewById(R.id.btn_01);
        textView = (TextView)this.findViewById(R.id.view_01);
        
        
        btnTest.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                //启动线程
                new MyThread().start();    
            }
        });
    }
    
    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText((String)msg.obj);
        }
    }    
    
    class MyThread extends Thread{
        
        public void run(){
            Looper.prepare(); //创建该线程的Looper对象
            //这里Looper.myLooper()获得的就是该线程的Looper对象了
            handler = new ThreadHandler(Looper.myLooper());
            Message msg = handler.obtainMessage(1,1,1,"我自己");
            handler.sendMessage(msg);
            
            Looper.loop(); 

        }
        
        //定义线程类中的消息处理类
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            public void handleMessage(Message msg){
                //这里对该线程中的MessageQueue中的Message进行处理
                //这里我们再返回给主线程一个消息
                //加入判断看看是不是该线程自己发的信息
                if(msg.what == 1 && msg.obj.equals("我自己")){
                    
                    handler = new MyHandler(Looper.getMainLooper());
                    
                    Message msg2 = handler.obtainMessage(1,1,1,"禀告主线程:我收到了自己发给自己的Message");
                    
                    handler.sendMessage(msg2);                
                }

            }
        }
    }
}

 

分享到:
评论

相关推荐

    多线程通信ThreadDemo

    在Java编程中,多线程通信是一个重要的概念,特别是在并发编程中。`ThreadDemo`示例可能演示了如何在不同的线程之间有效地传递信息。线程通信是解决多个执行流同步和协作的关键,确保数据的一致性和正确性。以下是...

    Android多线程文件上传

    本主题聚焦于"Android多线程文件上传",我们将探讨如何利用多线程技术来优化文件上传过程,提高效率,并确保应用的响应性。 一、多线程基础 多线程是并发执行多个任务的能力,它允许应用程序同时处理多个任务,提高...

    andriod多线程通信handler方法

    这就是Android多线程通信的基础原理。 至于压缩包中的文件,它们是Android Studio项目的一部分: - `gradlew.bat` 和 `gradlew` 是Gradle Wrapper,用于自动下载和执行Gradle。 - `.gitignore` 忽略某些文件或目录...

    Android多线程操作

    标题"Android多线程操作"和描述"Android多线程开发实例,对使用多线程的用户有一定的参考价值!"暗示我们将深入探讨Android中的线程管理以及如何在实践中有效利用。 Android系统默认运行在主线程,也被称为UI线程,...

    Android与PC机 Socket 多线程通信经典案例,移动开发必备代码

    以下是关于Android与PC机Socket多线程通信的关键知识点: 1. **Socket基础**:Socket是网络通信中的一个概念,它代表了两台机器间的一个连接端点,允许数据在网络中传输。在Java中,Socket类和ServerSocket类提供了...

    android多线程demo(很清晰很详细)

    本文将深入探讨Android多线程的相关知识点,基于“android多线程demo(很清晰很详细)”的描述,我们将围绕这个示例进行讲解。 1. **线程基础**: - **主线程**:Android应用的UI线程,负责处理用户交互和更新界面。...

    Android多线程下载

    **一、Android多线程下载** 1. **多线程概念**:多线程是指在一个程序中同时运行多个线程,每个线程处理不同的任务。在下载场景下,多线程意味着将一个大文件分割成多个小部分,每个部分由一个独立的线程负责下载。...

    android 多线程下载源代码

    综上所述,这个"android 多线程下载源代码"涵盖了Android并发编程、网络通信、文件操作等多个重要知识点,对于提升Android开发者处理大文件下载的能力非常有帮助。通过深入学习和实践,开发者可以更好地理解和掌握...

    Android多线程下载(二)

    总之,Android多线程下载涉及到了Android线程模型、并发控制、文件操作等多个方面,需要开发者有扎实的基础知识和实践经验。通过合理利用多线程,不仅可以提升应用性能,还能提高用户满意度。在实际开发中,要根据...

    android多线程

    ### Android多线程详解 #### 一、进程与线程概览 在深入探讨Android多线程之前,我们首先理解进程和线程的基本概念。**进程**是正在运行的程序实例,每个进程拥有自己独立的内存空间和系统资源。而**线程**则是...

    Android开发中的多线程编程技术

    在Android应用开发中,多线程技术是必不可少的,它能帮助开发者实现高效的代码执行,提升用户体验,并确保应用程序的响应性。本资源包主要聚焦于Android平台上的多线程编程,包括理论概念、最佳实践以及实际应用案例...

    Android 多线程图片下载开源代码

    1. Android多线程编程:线程池、AsyncTask、Handler/Looper、IntentService 2. 网络请求:HttpURLConnection、OkHttp 3. 图片处理与优化:Bitmap、LruCache、Fresco、Glide 4. 异步编程模型:Callback、LiveData、...

    Android 多线程断点续传下载

    在Android开发中,多线程断点续传...总之,Android多线程断点续传下载技术是提高用户体验的重要手段,涉及到了网络编程、多线程、文件操作、线程通信等多个技术领域,需要开发者具备扎实的基础和良好的问题解决能力。

    Android实现多线程下载

    在Android平台上,多线程下载是一项重要的技术,它允许应用程序同时从服务器获取数据,从而显著提高了文件下载的速度和效率。本教程将深入讲解如何在Android环境中实现多线程下载功能,以及涉及的相关知识点。 首先...

    Android多线程断点下载-IT计算机-毕业设计.zip

    总的来说,Android多线程断点下载涉及到Android的多线程编程、网络通信、数据库操作、服务管理和用户界面交互等多个方面,是Android应用开发中的一个重要实践。通过这样的毕业设计,学生不仅可以掌握相关技术,还能...

    Android 多线程下载简单demo之Thread

    总结来说,Android中的多线程下载涉及到网络通信、线程管理、文件操作等多个方面,通过合理的代码设计和优化,可以显著提高下载效率,提供更好的用户体验。通过阅读提供的博客文章和分析`DownloadTest`代码,开发者...

    android多线程实例

    2. **Handler-Looper-Message机制**:这是一种更复杂的多线程通信方式。在新线程中创建Handler对象,然后通过Looper循环消息队列,主线程中的Handler可以发送Message到新线程的Handler,从而实现数据交换。这种方式...

    android 多线程断点下载 (ListView 模式)

    通过以上步骤,我们可以构建一个功能完善的Android多线程断点下载应用,结合ListView展示下载任务,提供良好的用户交互体验。在实际开发中,还需要考虑各种边缘情况,进行充分的测试,以确保系统的稳定性和可靠性。

    Android多线程详解与Demo

    本文将深入探讨Android多线程的使用,包括其原理、常见方法以及如何通过实例进行实践。 首先,我们需要理解Android主线程,也被称为UI线程,它的主要任务是处理用户界面事件,如触摸事件、绘制视图等。如果在这个...

    Android中多线程下载原理实现案例

    总的来说,实现Android多线程下载涉及网络请求、线程管理、文件操作、数据同步等多个方面。开发者需要熟悉Android的并发编程模型,了解网络编程的基础知识,并掌握文件I/O的操作。通过这样的实践,不仅可以提高应用...

Global site tag (gtag.js) - Google Analytics