精华内容
下载资源
问答
  • Android 消息队列

    千次阅读 2019-06-09 17:37:30
    Android 消息队列 定义一个枚举类TaskPriority,定义任务的优先级 // 优先级分为3种,如注释所示,他们的关系:LOW < DEFAULT < HIGH public enum TaskPriority { LOW, //低 DEFAULT,//普通 ...

    Android 消息队列
    PriorityBlockingQueue(阻塞优先级队列)Comparable

    首先看看要封装的队列需要有什么功能

    在实际中,我们执行的任务大概可以分两种,一个是有明确的执行时间的,比如,要连续显示10个动画,每个展示5秒这种。一个是没明确的执行时间的,比如连续上传10张图片,每个上传任务的完成时间是需要等到上传成功回调回来才知道的这种。所以队列第一个功能是每个任务都可以兼容这两种情况,而且当然是一个执行完再执行下一个,排队执行

    既然要排队执行,当然会有优先级之分,所以每个任务都能设置优先级,队列可以根据优先级去排队执行任务

    1. 定义一个枚举类TaskPriority,定义任务的优先级
    // 优先级分为3种,如注释所示,他们的关系:LOW < DEFAULT < HIGH
    public enum TaskPriority {
        LOW, //低
        DEFAULT,//普通
        HIGH, //高
    }
    
    
    2. 队列任务执行时间确定和不确定两种情况的实现策略

    针对任务执行时间确定的这种情况,比较简单,可以给这个任务设置一个时间 duration,等任务开始执行时,便开始阻塞等待,等到时间到达时,才放开执行下一个任务

    针对任务执行时间不确定的情况,我们则需要在任务执行完成的回调里面手动放开,所以这里打算再用一个PriorityBlockingQueue队列,因为它有这样的一个特点:如果队列是空的,调用它的 take()方法时,它就会一直阻塞在那里,当列表不为空时,这个方法就不会阻塞。 所以当任务开始执行时,调用take()方法,等到我们的完成回调来时,再手动给它add一个值,阻塞就放开,再执行下一个任务

    3. 确定了任务两种情况的实现策略后,接下来定义一个接口,定义一下每个任务需要做什么事情
    public interface ITask extends Comparable<ITask> {
        
        // 将该任务插入队列
        void enqueue();
    
        // 执行具体任务的方法
        void doTask();
    
        // 任务执行完成后的回调方法
        void finishTask();
    
        // 设置任务优先级
        ITask setPriority(TaskPriority mTaskPriority);
    
        // 获取任务优先级
        TaskPriority getPriority();
    
        // 当优先级相同 按照插入顺序 先入先出 该方法用来标记插入顺序
        void setSequence(int mSequence);
    
        // 获取入队次序
        int getSequence();
    
        // 每个任务的状态,就是标记完成和未完成
        boolean getStatus();
        
        // 设置每个任务的执行时间,该方法用于任务执行时间确定的情况
        ITask setDuration(int duration);
        
        // 获取每个任务执行的时间
        int getDuration();
    
        // 阻塞任务执行,该方法用于任务执行时间不确定的情况
        void blockTask() throws Exception;
    
        // 解除阻塞任务,该方法用于任务执行时间不确定的情况
        void unLockBlock();
    }
    
    
    4. 封装一下PriorityBlockingQueue的基本功能
    public class BlockTaskQueue {
        private String TAG = "BlockTaskQueue";
        private AtomicInteger mAtomicInteger = new AtomicInteger();
        //阻塞队列
        private final BlockingQueue<ITask> mTaskQueue = new PriorityBlockingQueue<>();
    
        private BlockTaskQueue() {
        }
        //单例模式
        private static class BlockTaskQueueHolder {
            private final static BlockTaskQueue INSTANCE = new BlockTaskQueue();
        }
    
        public static BlockTaskQueue getInstance() {
            return BlockTaskQueueHolder.INSTANCE;
        }
    
        /**
         * 插入时 因为每一个Task都实现了comparable接口 所以队列会按照Task复写的compare()方法定义的优先级次序进行插入
         * 当优先级相同时,使用AtomicInteger原子类自增 来为每一个task 设置sequence,
         * sequence的作用是标记两个相同优先级的任务入队的次序
         */
        public <T extends ITask> int add(T task) {
            if (!mTaskQueue.contains(task)) {
                task.setSequence(mAtomicInteger.incrementAndGet());
                mTaskQueue.add(task);
                Log.d(TAG, "\n add task " + task.toString());
            }
            return mTaskQueue.size();
        }
    
        public <T extends ITask> void remove(T task) {
            if (mTaskQueue.contains(task)) {
                Log.d(TAG, "\n" + "task has been finished. remove it from task queue");
                mTaskQueue.remove(task);
            }
            if (mTaskQueue.size() == 0) {
                mAtomicInteger.set(0);
            }
        }
    
        public ITask poll() {
            return mTaskQueue.poll();
        }
    
        public ITask take() throws InterruptedException {
            return mTaskQueue.take();
        }
    
        public void clear() {
            mTaskQueue.clear();
        }
    
        public int size() {
            return mTaskQueue.size();
        }
    }
    
    5. 写一个类记录下当前执行的任务信息,方便获取时使用
    public class CurrentRunningTask {
        private static ITask sCurrentShowingTask;
    
        public static void setCurrentShowingTask(ITask task) {
            sCurrentShowingTask = task;
        }
    
        public static void removeCurrentShowingTask() {
            sCurrentShowingTask = null;
        }
    
        public static ITask getCurrentShowingTask() {
            return sCurrentShowingTask;
        }
    
        public static boolean getCurrentShowingStatus() {
            return sCurrentShowingTask != null && sCurrentShowingTask.getStatus();
        }
    }
    
    
    6. 封装一个基础的任务类
    public class BaseTask implements ITask {
        private final String TAG = getClass().getSimpleName();
        private TaskPriority mTaskPriority = TaskPriority.DEFAULT; //默认优先级
        private int mSequence;// 入队次序
        private Boolean mTaskStatus = false; // 标志任务状态,是否仍在展示
        protected WeakReference<BlockTaskQueue> taskQueue;//阻塞队列
        protected int duration = 0; //任务执行时间
        //此队列用来实现任务时间不确定的队列阻塞功能
        private PriorityBlockingQueue<Integer> blockQueue;
        //构造函数
        public BaseTask() {
            taskQueue = new WeakReference<>(BlockTaskQueue.getInstance());
            blockQueue = new PriorityBlockingQueue<>();
        }
        //入队实现
        @Override
        public void enqueue() {
            TaskScheduler.getInstance().enqueue(this);
        }
        //执行任务方法,此时标记为设为true,并且将当前任务记录下来
        @Override
        public void doTask() {
            mTaskStatus = true;
            CurrentRunningTask.setCurrentShowingTask(this);
        }
        //任务执行完成,改变标记位,将任务在队列中移除,并且把记录清除
        @Override
        public void finishTask() {
            this.mTaskStatus = false;
            this.taskQueue.get().remove(this);
            CurrentRunningTask.removeCurrentShowingTask();
            Log.d(TAG, taskQueue.get().size() + "");
        }
        //设置任务优先级实现
        @Override
        public ITask setPriority(TaskPriority mTaskPriority) {
            this.mTaskPriority = mTaskPriority;
            return this;
        }
        //设置任务执行时间
        public ITask setDuration(int duration) {
            this.duration = duration;
            return this;
        }
        //获取任务优先级
        @Override
        public TaskPriority getPriority() {
            return mTaskPriority;
        }
        //获取任务执行时间
        @Override
        public int getDuration() {
            return duration;
        }
        //设置任务次序
        @Override
        public void setSequence(int mSequence) {
            this.mSequence = mSequence;
        }
        //获取任务次序
        @Override
        public int getSequence() {
            return mSequence;
        }
        // 获取任务状态
        @Override
        public boolean getStatus() {
            return mTaskStatus;
        }
        //阻塞任务执行
        @Override
        public void blockTask() throws Exception {
            blockQueue.take(); //如果队列里面没数据,就会一直阻塞
        }
        //解除阻塞
         @Override
         public void unLockBlock() {
            blockQueue.add(1); //往里面随便添加一个数据,阻塞就会解除
         }
    
        /**
         * 排队实现
         * 优先级的标准如下:
         * TaskPriority.LOW < TaskPriority.DEFAULT < TaskPriority.HIGH
         * 当优先级相同 按照插入次序排队
         */
        @Override
        public int compareTo(ITask another) {
            final TaskPriority me = this.getPriority();
            final TaskPriority it = another.getPriority();
            return me == it ? this.getSequence() - another.getSequence() :
                    it.ordinal() - me.ordinal();
        }
        //输出一些信息
        @Override
        public String toString() {
            return "task name : " + getClass().getSimpleName() + " sequence : " + mSequence + " TaskPriority : " + mTaskPriority;
        }
    }
    
    
    7. TaskScheduler
    public class TaskScheduler {
        private final String TAG = "TaskScheduler";
        private BlockTaskQueue mTaskQueue = BlockTaskQueue.getInstance();
        private ShowTaskExecutor mExecutor;
    
        private static class ShowDurationHolder {
            private final static TaskScheduler INSTANCE = new TaskScheduler();
        }
    
        private TaskScheduler() {
            initExecutor();
        }
    
        private void initExecutor() {
            mExecutor = new ShowTaskExecutor(mTaskQueue);
            mExecutor.start();
        }
    
        public static TaskScheduler getInstance() {
            return ShowDurationHolder.INSTANCE;
        }
    
         public void enqueue(ITask task) {
            //因为TaskScheduler这里写成单例,如果isRunning改成false的话,不判断一下,就会一直都是false
            if (!mExecutor.isRunning()) {
                mExecutor.startRunning();
            }
            //按照优先级插入队列 依次播放
            mTaskQueue.add(task);
        }
    
        public void resetExecutor() {
            mExecutor.resetExecutor();
        }
    
        public void clearExecutor() {
            mExecutor.clearExecutor();
        }
    }
    
    
    8. 管理任务队列:ShowTaskExecutor
    public class ShowTaskExecutor {
        private final String TAG = "ShowTaskExecutor";
        private BlockTaskQueue taskQueue;
        private TaskHandler mTaskHandler;
        private boolean isRunning = true;
        private static final int MSG_EVENT_DO = 0;
        private static final int MSG_EVENT_FINISH = 1;
    
        public ShowTaskExecutor(BlockTaskQueue taskQueue) {
            this.taskQueue = taskQueue;
            mTaskHandler = new TaskHandler();
        }
        //开始遍历任务队列
        public void start() {
            AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (isRunning) { //死循环
                            ITask iTask;
                            iTask = taskQueue.take(); //取任务
                            if (iTask != null) {
                                //执行任务
                                TaskEvent doEvent = new TaskEvent();
                                doEvent.setTask(iTask);
                                doEvent.setEventType(TaskEvent.EventType.DO);
                                mTaskHandler.obtainMessage(MSG_EVENT_DO, doEvent).sendToTarget();
                                //一直阻塞,直到任务执行完
                                if (iTask.getDuration()!=0) {
                                    TimeUnit.MILLISECONDS.sleep(iTask.getDuration());
                                }else {
                                    iTask.blockTask();
                                }
                                //完成任务
                                TaskEvent finishEvent = new TaskEvent();
                                finishEvent.setTask(iTask);
                                finishEvent.setEventType(TaskEvent.EventType.FINISH);
                                mTaskHandler.obtainMessage(MSG_EVENT_FINISH, finishEvent).sendToTarget();
                            }
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
        //根据不同的消息回调不同的方法。
        private static class TaskHandler extends Handler {
            TaskHandler() {
                super(Looper.getMainLooper());
            }
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                TaskEvent taskEvent = (TaskEvent) msg.obj;
                if (msg.what == MSG_EVENT_DO && taskEvent.getEventType() == TaskEvent.EventType.DO) {
                    taskEvent.getTask().doTask();
                }
                if (msg.what == MSG_EVENT_FINISH && taskEvent.getEventType() == TaskEvent.EventType.FINISH) {
                    taskEvent.getTask().finishTask();
                }
            }
        }
    
        public void startRunning() {
            isRunning = true;
        }
    
        public void pauseRunning() {
            isRunning = false;
        }
    
        public boolean isRunning() {
            return isRunning;
        }
    
        public void resetExecutor() {
            isRunning = true;
            taskQueue.clear();
        }
    
        public void clearExecutor() {
            pauseRunning();
            taskQueue.clear();
        }
    }
    
    
    9. TaskEvent
    public class TaskEvent {
        private WeakReference<ITask> mTask;
        int mEventType;
    
        public ITask getTask() {
            return mTask.get();
        }
    
        public void setTask(ITask mTask) {
            this.mTask = new WeakReference<>(mTask);
        }
    
        public int getEventType() {
            return mEventType;
        }
    
        public void setEventType(int mEventType) {
            this.mEventType = mEventType;
        }
    
        public static class EventType {
            public static final int DO = 0X00;
            public static final int FINISH = 0X01;
        }
    }
    
    
    10.使用方法

    定义一个Task,继承 BaseTask,并实现对应的方法

    public class LogTask extends BaseTask {
        String name;
    
        public LogTask(String name) {
            this.name = name;
        }
    
        //执行任务方法,在这里实现你的任务具体内容
        @Override
        public void doTask() {
            super.doTask();
            Log.i("LogTask", "--doTask-" + name);
            
            //如果这个Task的执行时间是不确定的,比如上传图片,那么在上传成功后需要手动调用
            //unLockBlock方法解除阻塞,例如:
            uploadImage(new UploadListener{
               public void onSuccess() {
                    unLockBlock();
                }
            });
        }
    
    	private void uploadImage(UploadListener uploadListener) {
            try {
    //            long seconds = getDuration();
                long seconds = (long) (Math.random() * 10000);
                Log.i("LogTask", "uploadImage milliseconds " + seconds);
                Thread.sleep(seconds);
            } catch (Exception e) {
                e.printStackTrace();
            }
            uploadListener.onSuccess();
        }
        
        //任务执行完的回调,在这里你可以做些释放资源或者埋点之类的操作
        @Override
        public void finishTask() {
            super.finishTask();
            Log.i("LogTask", "--finishTask-" + name);
        }
    }
    
    public interface UploadListener {
        void onSuccess();
    }
    
    

    然后依次入队使用

    findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    new LogTask("任务2")
    //                        .setDuration(4000) // 设置了时间,代表这个任务时间是确定的,如果不确定,则不用设置
                            .setPriority(TaskPriority.DEFAULT) // 设置优先级,默认是DEFAULT
                            .enqueue(); // 入队
    
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
    
                            new LogTask("任务4")
    //                                .setDuration(4000) // 设置了时间,代表这个任务时间是确定的,如果不确定,则不用设置
                                    .setPriority(TaskPriority.LOW) // 设置优先级,默认是DEFAULT
                                    .enqueue(); // 入队
    
                            new LogTask("任务1")
    //                                .setDuration(6000) // 设置了时间,代表这个任务时间是确定的,如果不确定,则不用设置
                                    .setPriority(TaskPriority.LOW) // 设置优先级,默认是DEFAULT
                                    .enqueue(); // 入队
    
                            new LogTask("任务3")
    //                                .setDuration(2000) // 设置了时间,代表这个任务时间是确定的,如果不确定,则不用设置
                                    .setPriority(TaskPriority.HIGH) // 设置优先级,默认是DEFAULT
                                    .enqueue(); // 入队
    
                        }
                    },1000);
    
    
                }
            });
    
    
    参考
    1. 封装一个阻塞队列,轻松实现排队执行任务功能!
    2. 谈谈LinkedBlockingQueue
    3. BlockingQueue深入解析-BlockingQueue看这一篇就够了
    展开全文
  • Android消息队列

    千次阅读 2019-01-25 15:24:25
    Android消息队列 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout....

    Android消息队列

    public class MainActivity extends Activity { 
    
    	@Override 
    	protected void onCreate(Bundle savedInstanceState) { 
    		super.onCreate(savedInstanceState); 
    		setContentView(R.layout.activity_main);
    		m_LooperThread.start(); 
    	} 
    
    	private final static int MSG_NOTIFY = 0x10; 
    	private final static int MSG_EXIT = 0x20;
    	private LooperThread m_LooperThread = new LooperThread(); 
    	public void onClickSendNotifyMessage(View view) { 
    		m_LooperThread.mHandler.sendEmptyMessage(MSG_NOTIFY); 
    	}
    	public void onClickSendExitThreadLooper(View view) { 
    		m_LooperThread.mHandler.sendEmptyMessage(MSG_EXIT); 
    	} 
    	public class LooperThread extends Thread { 
    			public Handler mHandler = null; 
    			
    			@Override public void run() { 
    					Looper.prepare(); 
    					//在线程运行起来并且调用了Looper.prepare之后才定义Handler对象 
    					mHandler = new Handler() { 
    					@Override 
    					public void handleMessage(Message msg) { 
    						switch(msg.what) { 
    								case MSG_NOTIFY: 
    										Log.d("TestLooper", "Notify Message!"); 
    								break; 
    								case MSG_EXIT: //这里获得的是线程的Looper对象,故正常退出 
    										Looper.myLooper().quit(); 
    								break; 
    					}
    				 } 
    			 }; 
    		 Looper.loop();//该函数只有调用Looper的quit函数后才会返回 
    		 Log.d("TestLooper", "Exit the looper thread!"); 
    		 } 
    	 } 
     }
    
    展开全文
  • android消息队列

    2012-02-23 08:42:46
    android应用程序开发 多线程通信 消息队列
  • Android系统的消息队列消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列(Message Queue)和一个消息循环(Looper)。Android中除了UI线程(主线程),创建的工作线程默认是没有...
  • Android通过Looper、Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列消息循环)。Android系统中,Looper负责管理线程的消息队列消息循环。我们可以通过Loop.myLooper()...

    Android是参考Windows的消息循环机制来实现Android自身的消息循环的。

    Android通过Looper、Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环)。

    Android系统中,Looper负责管理线程的消息队列和消息循环。我们可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的Looper对象。

    一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper)。

    Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper)。

    Handler的作用是把消息加入特定的(Looper)消息队列中,并分发和处理该消息队列中的消息。构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前线程的Looper创建。

    Activity、Looper、Handler,Thread的关系如下图所示:

    image

    一个Activity中可以创建多个工作线程或者其他的组件,如果这些线程或者组件把他们的消息放入Activity的主线程消息队列,那么该消息就会在主线程中处理了。

    因为主线程一般负责界面的更新操作,并且Android系统中的widget不是线程安全的,所以这种方式可以很好的实现Android界面更新。在Android系统中这种方式有着广泛的运用。

    那么一个线程怎样把消息放入主线程的消息队列呢?答案是通过Handle对象,只要Handler对象以主线程的Looper创建,那么调用Handler的sendMessage等接口,将会把消息放入队列都将是放入主线程的消息队列。并且将会在Handler主线程中调用该handler的handleMessage接口来处理消息。

    更多Android消息队列的信息请参看: http://my.unix-center.net/~Simon_fu/?p=652

    下面这个图从另外一个角度描述了他们的关系:

    image

    参考资料:

    Android异步加载图像小结

    http://blog.csdn.net/sgl870927/archive/2011/03/29/6285535.aspx

    深入理解Android消息处理系统——Looper、Handler、Thread

    http://my.unix-center.net/~Simon_fu/?p=652

    Android线程模型(Painless Threading)

    http://android.group.iteye.com/group/blog/382683

    android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)

    http://lepeng.net/blogger/?p=21

    Android – Multithreading in a UI environment

    http://www.aviyehuda.com/2010/12/android-multithreading-in-a-ui-environment/

    Android中的Handler, Looper, MessageQueue和Thread

    http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html

    Android Runnable

    http://blog.csdn.net/michaelpp/archive/2010/06/30/5704682.aspx

    ---------------------

    展开全文
  • 在非UI线程使用Handler进行线程通信时,一般都需要进行3个步骤:创建Looper Looper.prepar()创建Handler启动消息循环Looper.loop()通过这3步,基本就建立好了 Android 的多线程消息通信机制:...通过 Handler 发送 ...

    在非UI线程使用Handler进行线程通信时,一般都需要进行3个步骤:

    创建Looper Looper.prepar()

    创建Handler

    启动消息循环Looper.loop()

    通过这3步,基本就建立好了 Android 的多线程消息通信机制:

    Handler

    MessageQueue

    Looper

    Message

    这几者可谓是你中有我,我中有你的存在。通过 Handler 发送 Message 到 Looper 的 MessageQueue 中,待 Looper 的循环执行到 Message 后,就会根据 Message 的 target handler,回调对应 Handler 的 handlerMessage 方法。

    例如: Thread-A 拥有一个 Looper,Thread-B 持有一个在 Thread-A 中构造的 Handler,Thread-B 就可以通过这个 Handler 将 Message 发送到 Thread-A 的 Looper 的 MessageQueue 中,然后消息会走到 Thread-A 的 Handler 的 handleMessage 方法。

    Looper 原理图

    f612393cf207aaba37b8d353d034dba7.png

    在 Looper 类加载时就会创建一个 ThreadLocal 类型的类变量 sThreadLocal

    public final class Looper {

    private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().

    static final ThreadLocal sThreadLocal = new ThreadLocal();

    Looper.prepar()

    public static void prepare() {

    prepare(true);

    }

    private static void prepare(boolean quitAllowed) {

    if (sThreadLocal.get() != null) {

    throw new RuntimeException("Only one Looper may be created per thread");

    }

    // 将构造的 looper 存到类变量 sThreadLocal 中

    sThreadLocal.set(new Looper(quitAllowed));

    }

    private Looper(boolean quitAllowed) {

    // 构建一个 messageQueue 成员

    mQueue = new MessageQueue(quitAllowed);

    // 将当前线程存入 mThread 中

    mThread = Thread.currentThread();

    }

    在这里面主要执行了 3 步:

    构建一个 looper

    构建一个 messageQueue 成员

    将当前线程存入 mThread 中

    将构造的 looper 存到类变量 sThreadLocal 中

    至此,执行 Looper.praper 的当前线程就会拥有一个 looper 成员了,存放在 Looper 的 sThreadLocal 中。

    创建Handler

    public Handler(Callback callback, boolean async) {

    ...

    // 通过`Looper.myLooper()` 类方法获取 sThreadLocal 中储存的当前线程的 looper,将这个 looper 绑定到 handler 的成员变量 mLooper 中

    mLooper = Looper.myLooper();

    if (mLooper == null) {

    throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");

    }

    // 将 mLooper 中的 messageQueue 绑定到 handler 的成员变量 mQueue 中

    mQueue = mLooper.mQueue;

    ...

    }

    public static @Nullable Looper myLooper() {

    return sThreadLocal.get();

    }

    Looper.loop()

    声明一个局部常量final Loop me = myLoop()

    myLoop()将返回当前线程的looper成员

    声明一个局部常量final MessageQueue queue

    将me.mQueue赋值给queue

    进入无限循环

    //进入无限循环

    for (;;) {

    //取出一条消息

    Message msg = queue.next();

    //没有消息就阻塞

    if (msg == null) {

    return;

    }

    ...

    //分发消息

    try {

    msg.target.dispatchMessage(msg);

    //msg.target是一个Handler对象

    } finally {

    if (traceTag != 0) {

    Trace.traceEnd(traceTag);

    }

    }

    ...

    //回收消息

    msg.recycleUnchecked();

    通过Message.obtain()获取的消息,需要使用Handler.sendMessage()插入到消息队列。

    通过Handler.obtainMessage()获取的消息,可以使用message.sendToTaget()插入到消息队列。

    ZWave 中的消息队列机制

    文章主题   在我们的日常编程中,对消息队列的需求非常常见,使用一个简洁.高效的消息队列编程模型,对于代码逻辑的清晰性,对于事件处理的高效率来说,是非常重要的.这篇文章就来看看 ZWave 中是通过什 ...

    Android消息队列和Looper

    1. 什么是消息队列 消息队列在android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what ...

    Android 消息分发机制

    Android 中针对耗时的操作,放在主线程操作,轻者会造成 UI 卡顿,重则会直接无响应,造成 Force Close.同时在 Android 3.0 以后,禁止在主线程进行网络请求. 针对耗时或者 ...

    Android开发学习—— 消息队列

    ###主线程不能被阻塞* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差* 主线程阻塞时间过长,系统会抛出ANR异常* ANR:Application ...

    Android 开发笔记 &OpenCurlyDoubleQuote;Android 的消息队列模型”

    Android是参考Windows的消息循环机制来实现Android自身的消息循环的. Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都 ...

    Android 的消息队列模型

    Android 的消息队列模型 Android是参考Windows的消息循环机制来实现Android自身的消息循环的.    Android通过Looper.Handler来实现消息循环机制,Andr ...

    Android HandlerThread 消息循环机制之源代码解析

    关于 HandlerThread 这个类.可能有些人眼睛一瞟,手指放在键盘上,然后就是一阵狂敲.立即就能敲出一段段华丽的代码: HandlerThread handlerThread = new Ha ...

    Window Azure ServiceBus Messaging消息队列技术系列1-基本概念和架构

    前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...

    跟我一起学WCF&lpar;1&rpar;——MSMQ消息队列

    一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...

    随机推荐

    【夯实PHP基础】UML序列图总结

    展开全文
  • Android消息队列原理

    2016-04-02 16:04:41
    安卓消息队列
  • Android 消息队列模型

    2016-04-08 09:54:44
    Android系统的消息队列消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列(Message Queue)和一个消息循环(Looper)。Android中除了UI线程(主线程),创建的工作线程默认是没有...
  • android消息队列机制

    2017-02-23 15:16:06
    1、只有主线程才能更新UI2、Message Queue(消息队列)随着主线程的创建而创建,用于存放消息 3、Looper(轮询器)随着主线程的创建而创建,用于轮询Message Queue中的消息 4、Handler消息处理器,利用handleMessage()来...
  • android消息队列很重要,应用开发几乎都要和它打交道。 涉及的四个主要的类:  Handler :消息队列的对外接口,接触最多  Message:队列中的节点  MessageQuene:提供enquene() , next()等方法  Looper:...
  • 回顾到消息队列部分, 便想着结合源码做一篇关于Android消息队列的讲解。然而,我深知这个主题已经被各种翻来覆去地讲, 各种刨根挖底地讲, 各种XXXX地讲… …各位同学应该也已经看烦了。 但是我还是决定写这么一篇...
  • 本节给大伙介绍:Android消息队列及线程机制:让大伙更了解Android消息驱动, 深入理解Android消息处理机制对于应用程序开发非常重要,也可以让你对线程同步有更加深刻的认识学会原理,对开发更有利,下面请看相关...
  • Android消息队列模型 Android是参考Windows的消息循环机制来实现Android自身的消息循环的。...Android通过Looper、Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列
  • 深入理解Android消息队列原理篇

    千次阅读 2012-02-10 10:52:17
    本篇深入理解Android消息队列原理篇,将为您讲述Android世界中的消息机制,无论是android线程内部或者线程之间,当它们进行信息交互时,则会传递这些消息,为此,深入理解这些消息队列原理,将有助于我们更好的掌握...
  • 二,Android消息队列--异步消息处理 异步消息处理 简介: 对于普通的线程来说,执行完run()方法内的代码后线程就结束了。而异步消息处理线程是指:线程启动后会进入一个无限循环体之中,每执行一次,从线程内部的...
  • Android消息队列总结

    千次阅读 2017-03-07 13:53:43
    一,使用Handler的流程 ...在事件监听器中调用Handler的post方法,将要执行的线程对象添加到线程队列中,将要执行的操作写在线程对象的run方法中,一般是一个Runnable对象,复写其中的run方法 Handler对象管理
  • 本篇深入理解Android消息队列原理篇,将为您讲述Android世界中的消息机制,无论是android线程内部或者线程之间,当它们进行信息交互时,则会传递这些消息,为此,深入理解这些消息队列原理,将有助于我们更好的掌握...
  • Android消息队列和Looper

    2015-02-05 12:07:00
    消息队列android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what)或者一串动作(Runnable),有两处会用到Message:Handler和...
  • ConcurrentLinkedQueue 非阻塞线程队列 LinkedBlockingQueue 阻塞线程队列
  • /** * Causes the Runnable r to be added to the message queue. ... //调用消息队列里面的enqueueMessage,传进去消息和延时时间,这个实例里面传的是0. return queue.enqueueMessage(msg, uptimeMillis); }
  • Android消息队列图片记录

    千次阅读 2015-08-13 22:37:02
    很早之前为了给学生讲明白整个消息队列是怎么个情况,于是大概阅读了一下消息队列的整个工作做成,鉴于网上大部分都是文字说明,没有一个图例,于是做出了下面这张图,权当作以后复习只用,也供大家学习参考,有什么...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 105,669
精华内容 42,267
关键字:

安卓消息队列