Handler线程间通信

  1 package com.hixin.appexplorer;
  2
  3 import java.util.List;
  4
  5 import android.app.Activity;
  6 import android.app.ProgressDialog;
  7 import android.content.Context;
  8 import android.content.pm.PackageInfo;
  9 import android.content.pm.PackageManager;
 10 import android.os.Bundle;
 11 import android.os.Handler;
 12 import android.os.Message;
 13 import android.view.LayoutInflater;
 14 import android.view.View;
 15 import android.view.ViewGroup;
 16 import android.view.Window;
 17 import android.view.WindowManager;
 18 import android.widget.BaseAdapter;
 19 import android.widget.GridView;
 20 import android.widget.ImageView;
 21 import android.widget.TextView;
 22
 23 public class MainActivity extends Activity implements Runnable {
 24
 25     GridView gv;
 26     private List<PackageInfo> packageInfos;
 27     private ProgressDialog pd;
 28     private Handler mHandler = new Handler() {
 29         @Override
 30         public void handleMessage(Message msg) {
 31             // TODO Auto-generated method stub
 32             super.handleMessage(msg);
 33             gv.setAdapter(new GridViewAdapter(MainActivity.this));
 34             pd.dismiss();
 35             setProgressBarIndeterminateVisibility(false);
 36         }
 37
 38     };
 39     @Override
 40     protected void onCreate(Bundle savedInstanceState) {
 41         super.onCreate(savedInstanceState);
 42     //    requestWindowFeature(Window.FEATURE_NO_TITLE);
 43         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
 44         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
 45         setContentView(R.layout.show_app_grid);
 46
 47         gv = (GridView)this.findViewById(R.id.gv_apps);
 48         pd = ProgressDialog.show(this,"请稍候...", "正在搜索你所安装的应用程序",true,false);
 49         setProgressBarIndeterminateVisibility(true);
 50         Thread t = new Thread(this);
 51         t.start();
 52         }
 53
 54     @Override
 55     public void run() {
 56         // TODO Auto-generated method stub
 57         packageInfos = getPackageManager().getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
 58         try {
 59             Thread.sleep(2000);
 60         } catch (InterruptedException e) {
 61             // TODO Auto-generated catch block
 62             e.printStackTrace();
 63         }
 64         mHandler.sendEmptyMessage(0);
 65     }
 66
 67
 68     class GridViewAdapter extends BaseAdapter{
 69
 70         LayoutInflater inflater;
 71         public GridViewAdapter(Context context) {
 72             inflater = LayoutInflater.from(context);
 73         }
 74         @Override
 75         public int getCount() {
 76             // TODO Auto-generated method stub
 77             return packageInfos.size();
 78         }
 79
 80         @Override
 81         public Object getItem(int position) {
 82             // TODO Auto-generated method stub
 83             return packageInfos.get(position);
 84         }
 85
 86         @Override
 87         public long getItemId(int position) {
 88             // TODO Auto-generated method stub
 89             return position;
 90         }
 91
 92         @Override
 93         public View getView(int position, View convertView, ViewGroup parent) {
 94             // TODO Auto-generated method stub
 95
 96                 View view = inflater.inflate(R.layout.gv_item, null);
 97                 TextView tv = (TextView)view.findViewById(R.id.gv_item_appname);
 98                 ImageView iv = (ImageView)view.findViewById(R.id.gv_item_icon);
 99                 tv.setText(packageInfos.get(position).applicationInfo.loadLabel(getPackageManager()));
100                 iv.setImageDrawable(packageInfos.get(position).applicationInfo.loadIcon(getPackageManager()));
101
102             return view;
103         }
104
105     }
106
107 }
108
109     

当需要显示的项目很多,会造成很大的延迟。这时候屏幕会一直黑屏。给用户很不好的体验。应该在获取信息的时候,显示一些进度信息给用户看,增加用户体验。

程序在期间获取安装程序信息,主界面上显示进度条,当信息获取完毕之后(获取信息在新线程里执行),发送一条消息通知主线程,主线程关掉进度条,加载列表。

一、基本概念

Looper:每一个线程都可以产生一个Looper,用来管理线程的Message,Looper对象会建立一个MessgaeQueue数据结构来存放message。

Handler:与Looper沟通的对象,可以push消息或者runnable对象到MessgaeQueue,也可以从MessageQueue得到消息。

线程A的Handler对象引用可以传递给别的线程,让别的线程B或C等能送消息来给线程A。

线程A的Message Queue里的消息,只有线程A所属的对象可以处理。

注意:Android里没有global的MessageQueue,不同进程(或APK之间)不能通过MessageQueue交换消息。

本例中线程A就是UI线程,线程B就是新建的处理线程

时间: 2024-10-12 12:46:56

Handler线程间通信的相关文章

android 中的 Handler 线程间通信

一. 在MainActivity中为什么只是类似的写一行如下代码就可以使用handler了呢? Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // handle the nsg message... } }; private void sendMessage() { handler.sendEmptyMessage(11); } 打开handler的源码可以在它的构造函数中

Android中线程间通信原理分析:Looper,MessageQueue,Handler

自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么做? 以上者两个问题,是我最近总结出来的,在我们学习了解一个新的技术之前,最好是先能回答这两个问题,这样你才能对你正在学习的东西有更深刻的认识. 第一个问题:google的程序员们搞出这一套东西是为了解决什么问题的?这个问题很显而易见,为了解决线程间通信的问题.我们都知道,Android的UI/Vi

线程间通信: Handler , Looper, MessageQueue, Message (完结)

概述:    为了 线程间 通信方便, Handler 机制 通过 Handler 和 Looper, MessageQueue, Message 这些 类 之间的协作, 简化 多线程的开发.  线程的交互 会被封装 到 Message 中, 然后 通过 Handler 的方法 把 消息 放到 MessageQueue 消息队列中, 实现 Handler 机制的线程 都会 调用 Looper 的 loop() 方法, 则 Looper 作为 消息分发者的 作用就体现出来了.  loop() 方法

线程间通信原理

从操作系统的角度讲,线程间通信比进程间通信要容易的多,因为线程之间可以共享进程的内存空间.因此,他们可以共享位于进程全局数据区和栈和堆上的所有内容. 唯一只属于某个线程的就是线程的栈-------它可以存放只属于线程的对象. 下面逐一解读线程间通信方式: 1.   共享进程的变量 这是最基本的通信方式,但要注意不要共享线程栈上的变量,因为它随时可能被某个线程销毁,而另一个线程就无法访问它了. 所以Java编译器不允许使用栈上的变量来共享. 例子1: 如下面这个编译器是会报错的, protecte

Android 线程间通信

进程与线程的区别? 在Android中,线程是跑在进程之中的,当手机打开一个APP就相当于打开了一个进程,比如:UI界面的更新,就是在主线程中完成的,我也可以自定义一些子线程来完成所需要的任务. 如何创建线程?创建线程的几种方式? 1.创建一个类继承Thread类 2.创建一个类实现Runnable接口 什么是多线程? 线程是程序中一个单一的顺序控制流程,在程序中同是运行多个线程完成不同的工作,称为多线程 ANR的基础知识及产生? ANR:application not responding :

Net线程间通信的异步机制

线程间通信 我们看下面的图 我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), 线程B通过调用线程A的同步上下文对象来访问线程A,所有实现都是在同步上下文中完成的.线程B有两种方式来实现线程间的通信. 第一种:调用线程A的同步上下文对象,阻碍当前线程,执行红色箭头调用,直到黄色箭头返回(同步上下文执行完毕)才释放当前线程. (1->2->3->5) 第二种:调用线程A的

【转】VC 线程间通信的三种方式

原文网址:http://my.oschina.net/laopiao/blog/94728 1.使用全局变量(窗体不适用)      实现线程间通信的方法有很多,常用的主要是通过全局变量.自定义消息和事件对象等来实现的.其中又以对全局变量的使用最为简洁.该方法将全局变量作为线程监视的对象,并通过在主线程对此变量值的改变而实现对子线程的控制.      由于这里的全局变量需要在使用它的线程之外对其值进行改变,这就需要通过volatile关键字对此变量进行说明.使用全局变量进行线程通信的方法非常简单

iOS开发NSOperation 三:操作依赖和监听以及线程间通信

一:操作依赖和监听 #import "ViewController.h" @interface ViewController () @end @implementation ViewController /** * 1:NSOperation的使用:1:先创建队列NSOperationQueue:若不创建队列直接封装任务则默认在当前线程中串行执行任务,其队列分为两种主队列和非主队列,主队列和GCD中的主队列一样[NSOperationQueue mainQueue],而alloc in

线程间通信和线程互斥

线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后在主线程刷新UI界面 视图布局我就不写了,大家自己来吧,线程间通信代码如下: #pragma mark - 添加响应方法触发创建子线程并加载数据 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event