收藏本站 收藏本站
积木网首页 - 软件测试 - 常用手册 - 站长工具 - 技术社区
首页 > Android > Android基础 > 正文

首页 - PHP - 数据库 - 操作系统 - 游戏开发 - JS - Android - MySql - Redis - MongoDB - Win8 - Shell编程 - DOS命令 - jQuery - CSS样式 - Python - Perl

Access - Oracle - DB2 - SQLServer - MsSql2008 - MsSql2005 - Sqlite - PostgreSQL - node.js - extjs - JavaScript vbs - Powershell - Ruby

android:Background线程池和UiThread线程池

由来

希望在代码的任何地方,无论是在Ui线程中调用,还是Thread中调用,都能指定Runnable执行的所在的线程池。

Codes
package com.example.androidbackgroundexecuter;

import java.util.concurrent.Executor;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.MessageQueue;

/**
 * 
 * @author Zheng Haibo
 * @Web http://www.mobctrl.net
 *
 */
public final class GlobalExecutor implements Executor {

    static final String APP_EXECUTOR = "APP_EXECUTER";

    private final Handler mainHandler;
    private final Handler backgroundHandler;

    public GlobalExecutor() {
        if (!isOnMainThread()) {
            throw new IllegalStateException(
                    "Error!Please init the Executor in the main thread...");
        }
        mainHandler = new Handler(Looper.getMainLooper());
        HandlerThread handlerThread = new HandlerThread(APP_EXECUTOR);
        handlerThread.start();
        backgroundHandler = new Handler(handlerThread.getLooper());
    }

    @Override
    public void execute(final Runnable command) {
        executeInBackground(command, 0);
    }

    /**
     * execute the command in background thread with a delay of {@link #delay}
     * 
     * @param command
     */
    public void execute(final Runnable command, int delay) {
        executeInBackground(command, delay);
    }

    /**
     * execute the command in UiThread
     * 
     * @param command
     */
    public void executeInUiThread(final Runnable command) {
        mainHandler.post(command);
    }

    /**
     * execute the command in main thread with a delay of {@link #delay}
     * 
     * @param command
     */
    public void executeInUiThread(final Runnable command, int delay) {
        mainHandler.postDelayed(command, delay);
    }

    /**
     * execute the command in background thread with a delay of {@link #delay}
     * 
     * @param command
     */
    public void executeInBackground(final Runnable command, final int delay) {
        if (isOnMainThread()) {
            executeDelayedAfterIdleUnsafe(command, delay);
        } else {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    executeDelayedAfterIdleUnsafe(command, delay);
                }
            });
        }
    }

    /**
     * execute the command in background thread
     * 
     * @param command
     */
    public void executeInBackground(final Runnable command) {
        executeInBackground(command, 0);
    }

    private boolean isOnMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

    private void executeDelayedAfterIdleUnsafe(final Runnable task,
            final int delay) {
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                backgroundHandler.postDelayed(task, delay);
                return false;
            }
        });
    }
}

注意,new GlobalExecutor()是需要在主线程。

使用举例
package com.example.androidbackgroundexecuter;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Process;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    private GlobalExecutor mGlobalExecutor = null;

    private Button btn1;
    private Button btn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mGlobalExecutor = new GlobalExecutor();
        btn1 = (Button) findViewById(R.id.btn_1);
        btn1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                System.out.println("debug:btn 1 click");
                btn1.setBackgroundColor(Color.BLACK);
                mGlobalExecutor.execute(new Runnable() {

                    @Override
                    public void run() {
                        System.out.println("debug:click1 execute tid = "
                                + Process.myTid() + ",pid=" + Process.myPid());
                    }
                });

                mGlobalExecutor.executeInUiThread(new Runnable() {

                    @Override
                    public void run() {
                        System.out
                                .println("debug: click1 executeInUiThread tid = "
                                        + Process.myTid()
                                        + ",pid="
                                        + Process.myPid());
                    }
                });
            }
        });

        btn2 = (Button) findViewById(R.id.btn_2);
        btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                System.out.println("debug:btn 2 click");
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        System.out.println("debug: click2(run) tid = "
                                + Process.myTid() + ",pid=" + Process.myPid());
                        mGlobalExecutor.execute(new Runnable() {

                            @Override
                            public void run() {
                                System.out
                                        .println("debug: click2 run execute in thread- tid = "
                                                + Process.myTid()
                                                + ",pid="
                                                + Process.myPid());
                            }
                        });

                        mGlobalExecutor
                                .executeInUiThread(new Runnable() {

                                    @Override
                                    public void run() {
                                        System.out
                                                .println("debug: click2 run execute in UiThread- tid = "
                                                        + Process.myTid()
                                                        + ",pid="
                                                        + Process.myPid());
                                        btn1.setBackgroundColor(Color.RED);
                                    }
                                });

                    }
                }).start();
            }
        });
    }
}
Print

相继点击按钮btn1和btn2,日志如下:

05-20 10:25:49.045: I/System.out(3144): debug:btn 1 click
05-20 10:25:49.115: I/System.out(3144): debug: click1 executeInUiThread tid = 3144,pid=3144
05-20 10:25:49.125: I/System.out(3144): debug:click1 execute tid = 3157,pid=3144
05-20 10:25:50.105: I/System.out(3144): debug:btn 2 click
05-20 10:25:50.105: I/System.out(3144): debug: click2(run) tid = 3582,pid=3144
05-20 10:25:50.145: I/System.out(3144): debug: click2 run execute in UiThread- tid = 3144,pid=3144
05-20 10:25:50.175: I/System.out(3144): debug: click2 run execute in thread- tid = 3157,pid=3144
优点

我们可以在任意线程中调用我们想执行的Runnable,非常方便。

更多交流

Android开发联盟QQ群:272209595

Android:Otto源码分析
Otto源码分析Otto是一个轻量级的EventBus,它的使用非常简单,我们使用一个Bus的单例,所有需要产生事件(@Producebus.post(newYourEvent(…)))或者处理事件(@Subscri

Android:ValueAnimator的使用举例
由来很多人对ValueAnimator不熟悉,其实ValueAnimator的功能是非常强大的。它按照设定的时间和规则,在Update方法中将value友from变化到to。说起来很简单~动画

android:模拟水波效果的自定义View
Github地址:https://github.com/nuptboyzhb/WaterWaveView欢迎Fork,欢迎Star1.先看效果2.再看关键代码描绘函数y=Asin(wx+d)+offset/***使用路径描绘绘制的区域**@return*/privat

本周排行

更新排行

强悍的草根IT技术社区,这里应该有您想要的! 友情链接:b2b电子商务
Copyright © 2010 Gimoo.Net. All Rights Rreserved  京ICP备05050695号