<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Android Resource &#124; 资源 资讯 教程 &#187; Handler</title>
	<atom:link href="http://www.androidres.com/index.php/tag/handler/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.androidres.com</link>
	<description>Discuss developing Android applications using the Android framework and Collect android resource</description>
	<lastBuildDate>Tue, 12 Jan 2010 10:03:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- Easy AdSense V2.82 -->
<!-- Post[count: 1] -->
<div class="ezAdsense adsense adsense-leadin" style="text-align:center;margin:12px;"><script type="text/javascript"><!--
google_ad_client = "pub-4703322803494425";
/* 468x60, Top_SinglePost */
google_ad_slot = "7939142022";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>	<item>
		<title>Dialog工具箱 &#8211; ProgressDialog</title>
		<link>http://www.androidres.com/index.php/2009/09/13/android-progressdialog-tutorials/</link>
		<comments>http://www.androidres.com/index.php/2009/09/13/android-progressdialog-tutorials/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 19:29:23 +0000</pubDate>
		<dc:creator>EGGer</dc:creator>
				<category><![CDATA[Resource]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Handler]]></category>
		<category><![CDATA[ProgessBar]]></category>
		<category><![CDATA[ProgressDialog]]></category>
		<category><![CDATA[Thread]]></category>

		<guid isPermaLink="false">http://www.androidres.com/?p=650</guid>
		<description><![CDATA[在此前的几个教程中引出过一些Dialog的使用方法，可从来没有系统全面的介绍Android平台上所有Dialog家族成员的情况（其实官方文档有相当明确的说明：参考1、参考2）。对于大部分人可以直接根据官方文档获得有关Dialog的使用方法，AR给出的有关Dialog参考教程可以作为额外的补充。
在这里为大家介绍ProgressDialog的使用方法：

1) 创建一个普通ProgressDialog（不带有ProgressBar）所必须的几个参数

Context: 指定当前Dialog的Container
Title:对话框标题
Message:对话框主体所显示的信息
Indeterminate:不确定性属性，这个属性对于ProgressDailog默认的转轮模式没有实际意义，默认下设置为true，它仅仅对带有ProgressBar的Dialog有作用。

2）以下两个为可选参数

Cancelable:增加一个可以Cancel当前Dialog的按钮，强制退出。
CancelListner:当前Dialog强制取消之后将会被执行，通常用来清理未完成的任务。

快速创建一个ProgressDialog的方法（代码片段）：
    private ProgressDialog dialog;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg)
        {
        	dialog.dismiss();
        }
  [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">在此前的几个教程中引出过一些Dialog的使用方法，可从来没有系统全面的介绍Android平台上所有Dialog家族成员的情况（其实官方文档有相当明确的说明：<a target="_blank" href="http://developer.android.com/guide/topics/ui/dialogs.html" target="_blank">参考1</a>、<a target="_blank" href="http://developer.android.com/reference/android/app/Dialog.html" target="_blank">参考2</a>）。对于大部分人可以直接根据官方文档获得有关Dialog的使用方法，AR给出的有关Dialog参考教程可以作为额外的补充。</p>
<p style="text-align: left;">在这里为大家介绍<a target="_blank" href="http://developer.android.com/reference/android/app/ProgressDialog.html" target="_blank">ProgressDialog</a>的使用方法：</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-651" style="border: 3px solid #e6e6e6;" title="ProgressDialog" src="http://www.androidres.com/wp-content/uploads/2009/09/ProgressDialog.jpg" alt="ProgressDialog" width="288" height="142" /></p>
<p>1) 创建一个普通ProgressDialog（不带有ProgressBar）所必须的几个参数</p>
<ul>
<li>Context: 指定当前Dialog的Container</li>
<li>Title:对话框标题</li>
<li>Message:对话框主体所显示的信息</li>
<li>Indeterminate:不确定性属性，这个属性对于ProgressDailog默认的转轮模式没有实际意义，默认下设置为true，它仅仅对带有ProgressBar的Dialog有作用。</li>
</ul>
<p>2）以下两个为可选参数</p>
<ul>
<li>Cancelable:增加一个可以Cancel当前Dialog的按钮，强制退出。</li>
<li>CancelListner:当前Dialog强制取消之后将会被执行，通常用来清理未完成的任务。</li>
</ul>
<p>快速创建一个ProgressDialog的方法（代码片段）：</p>
<pre class="brush: java; smart-tabs: true;toolbar: false">    private ProgressDialog dialog;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg)
        {
        	dialog.dismiss();
        }
    };
    private Thread checkUpdate = new Thread()
    {
    	public void run() {  

    	  try {
			sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	  handler.sendEmptyMessage(0);
    	}
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);    

	    final Button button = (Button) findViewById(R.id.Compute);
	    button.setOnClickListener(new View.OnClickListener()
	    {

			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				checkUpdate.stop();
				dialog = ProgressDialog.show(ARTestDrawing2D.this,
					      "AndroidRes",
						  "I am thinking...",
						  true,true);
				checkUpdate.start();
			}

	    });
    }</pre>
<p style="text-align: left;">上边的例子中引用了<a target="_blank" href="http://developer.android.com/reference/android/os/Handler.html" target="_blank">Handler</a>（official）作为multi-thread<a href="http://www.androidres.com/?p=456" target="_blank">相互传递数据</a>的载体，接下来为ProgressDialog实现一个可视化进度条(progressBar)的方法中依然需要调用<a href="http://www.androidres.com/?p=330" target="_blank">Handler</a>(Internal)，借用这个例子大家也可以多了解Handler的用法。</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-652" style="border: 3px solid #e6e6e6;" title="ProgressBar" src="http://www.androidres.com/wp-content/uploads/2009/09/ProgressBar.jpg" alt="ProgressBar" width="292" height="187" /></p>
<p>利用一个可视化进度条取代第一个例子中比较抽象的旋转轮，让用户更加直观的了解当前任务的进度。初始化的方法如下：</p>
<pre class="brush: java; smart-tabs: true;toolbar: false">dialog = new ProgressDialog(ARTestDrawing2D.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setTitle("AndroidRes");
dialog.setMessage("I am thinking...");</pre>
<p>看起来稍微比第一个例子复杂一些，每个参数都单独利用成员方法赋值。<br />
其中SetProgressStyle用来设置显示模式，通常为STYLE_HORIZONTAL。下边通过一个完整的例子了解它的初始化和设置方法（例子来源于<a target="_blank" href="http://developer.android.com/guide/topics/ui/dialogs.html" target="_blank">Android官网</a>）：</p>
<pre class="brush: java; smart-tabs: true;toolbar: false">    static final int PROGRESS_DIALOG = 0;
    Button button;
    ProgressThread checkUpdate;
    ProgressDialog dialog;

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Setup the button that starts the progress dialog
        button = (Button) findViewById(R.id.Compute);
        button.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                showDialog(PROGRESS_DIALOG);
            }
        });
    }

    protected Dialog onCreateDialog(int id) {
        switch(id) {
        case PROGRESS_DIALOG:
        	dialog = new ProgressDialog(ARTestDrawing2D.this);
        	dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        	dialog.setTitle("AndroidRes");
        	dialog.setMessage("I am thinking...");
        	checkUpdate = new ProgressThread(handler);
        	checkUpdate.start();
            return dialog;
        default:
            return null;
        }
    }

    // Define the Handler that receives messages from the thread and update the progress
    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            int total = msg.getData().getInt("total");
            dialog.setProgress(total);
            if (total &gt;= 100){
                dismissDialog(PROGRESS_DIALOG);
                checkUpdate.setState(ProgressThread.STATE_DONE);
                total = 0;
            }
        }
    };

    /** Nested class that performs progress calculations (counting) */
    private class ProgressThread extends Thread {
        Handler mHandler;
        final static int STATE_DONE = 0;
        final static int STATE_RUNNING = 1;
        int mState;
        int total;

        ProgressThread(Handler h) {
            mHandler = h;
        }

        public void run() {
            mState = STATE_RUNNING;
            total = 0;
            while (mState == STATE_RUNNING) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Log.e("ERROR", "AndroidRes Thread Interrupted");
                }
                Message msg = mHandler.obtainMessage();
                Bundle b = new Bundle();
                b.putInt("total", total);
                msg.setData(b);
                mHandler.sendMessage(msg);
                total++;
            }
        }

        /* sets the current state for the thread,
         * used to stop the thread */
        public void setState(int state) {
            mState = state;
        }
    }</pre>
<p>例子理解起来相对比较容易，对两个比较主要的对象做个简单的说明：<br />
<strong>checkUpdate</strong>: 从主线程中创建一个用于计算某项任务的线程，同时也是利用ProgessBar所追踪的对象，指示这个线程的任务进度。<br />
<strong>handler</strong>: 利用这个Handler可以将线程中的数据实时反映到主线程中的ProgessBar，使其可以实时接收到最新进度数据。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.androidres.com/index.php/2009/09/13/android-progressdialog-tutorials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>线程间相互传递信息的方法</title>
		<link>http://www.androidres.com/index.php/2009/05/21/android-communicating-among-multi-threads/</link>
		<comments>http://www.androidres.com/index.php/2009/05/21/android-communicating-among-multi-threads/#comments</comments>
		<pubDate>Thu, 21 May 2009 14:24:34 +0000</pubDate>
		<dc:creator>EGGer</dc:creator>
				<category><![CDATA[Resource]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Handler]]></category>
		<category><![CDATA[Threads]]></category>

		<guid isPermaLink="false">http://www.androidres.com/?p=456</guid>
		<description><![CDATA[最重要的是理解实现线程间相互传递信息的目的，例如：有专门的线程来实时跟踪某些状态信息，当需要在某些Activity的线程(例如：Rendering Thread)中调用实时状态信息时，经常采用线程间相互共享数据方法。
对于没有过类似需求的开发者来讲，在这个过程中需要更加细心的了解每个步骤所代表的含义，而且必要时可以在文章后边提出困惑的问题。
这个例子的代码相比以前稍微多了一些，有必要强调阅读代码的技巧。分析别人写的代码是一件非常艰巨的任务，尤其是面对庞大的类群或者在缺少注释的环境下。有经验的程序员在摸爬滚打中都培养出各自习惯的方式来处理各种棘手的问题。无论有哪些方法，其所具备的共同点是要细心的对待每一行代码，具备耐心和目的性，要了解当前所分析的代码实现的功能。不在这里更深入的讨论这个话题，向有感兴趣的朋友推荐一本讲述如何阅读代码的参考资料《Code Reading》，这个作者另外一本值得阅读的书是《Code Quality》，都值得阅读。
这次要分析的代码来自AndroidSnippets.org，对于经常光顾AR的朋友应该非常了解，本站对于他们的内容时刻保持着关注，除了粘贴一些例子以外，更主要的是剖析例子中所涉及的知识点，这是体现AndroidRes存在价值的方式。上边的一些话扯的稍远了点，让我们回到正题吧。
介绍本例中两个最基本的类：其中第一个是承载HandlerThread和Handler的类，另外一个是用来装载实例的容器，二者的关系可以看作为玻璃球和玻璃球罐子。
先来分析第一个类，“玻璃球”的内部除了包括HandlerThread和Handler以外，还需要创建一个默认的消息响应类，为了体现很好的拓展性，可以在声明“玻璃球”类时指定其它HandleMessage方法。下边先来看完整的源代码（保留原有英文注释）：

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Handler.Callback;
import android.util.Log;  

/**
 * The transceiver provides a convenient way to decorate an instance with receive and transmit capabilities.
 * It can (and this is encouraged) be used with the {@link Broker} instance.
 * The naming thing is not part of the Transeiver's functionality, but may be [...]]]></description>
			<content:encoded><![CDATA[<p>最重要的是理解实现线程间相互传递信息的目的，例如：有专门的线程来实时跟踪某些状态信息，当需要在某些Activity的线程(例如：Rendering Thread)中调用实时状态信息时，经常采用线程间相互共享数据方法。<span id="more-456"></span></p>
<p>对于没有过类似需求的开发者来讲，在这个过程中需要更加细心的了解每个步骤所代表的含义，而且必要时可以在文章后边提出困惑的问题。</p>
<p>这个例子的代码相比以前稍微多了一些，有必要强调阅读代码的技巧。分析别人写的代码是一件非常艰巨的任务，尤其是面对庞大的类群或者在缺少注释的环境下。有经验的程序员在摸爬滚打中都培养出各自习惯的方式来处理各种棘手的问题。无论有哪些方法，其所具备的共同点是要细心的对待每一行代码，具备耐心和目的性，要了解当前所分析的代码实现的功能。不在这里更深入的讨论这个话题，向有感兴趣的朋友<a target="_blank" href="http://www.spinellis.gr/codereading/" target="_blank">推荐一本讲述如何阅读代码的参考资料《Code Reading》</a>，这个作者另外一本值得阅读的书是<a target="_blank" href="http://www.spinellis.gr/codequality/" target="_blank">《Code Quality》</a>，都值得阅读。</p>
<p>这次要分析的代码来自<a target="_blank" href="http://www.androidsnippets.org">AndroidSnippets.org</a>，对于经常光顾AR的朋友应该非常了解，本站对于他们的内容时刻保持着关注，除了粘贴一些例子以外，更主要的是剖析例子中所涉及的知识点，这是体现<a href="http://www.androidres.com" target="_blank">AndroidRes</a>存在价值的方式。上边的一些话扯的稍远了点，让我们回到正题吧。</p>
<p>介绍本例中两个最基本的类：其中第一个是承载<a target="_blank" href="http://developer.android.com/reference/android/os/HandlerThread.html">HandlerThread</a>和<a target="_blank" href="http://developer.android.com/reference/android/os/Handler.html" target="_blank">Handler</a>的类，另外一个是用来装载实例的容器，二者的关系可以看作为玻璃球和玻璃球罐子。</p>
<p>先来分析第一个类，“<span style="color: #008000;">玻璃球</span>”的内部除了包括HandlerThread和Handler以外，还需要创建一个默认的消息响应类，为了体现很好的拓展性，可以在声明“玻璃球”类时指定其它<a target="_blank" href="http://developer.android.com/reference/android/os/Handler.html#handleMessage(android.os.Message)" target="_blank">HandleMessage</a>方法。<strong>下边先来看完整的源代码（保留原有英文注释）：</strong></p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Handler.Callback;
import android.util.Log;  

/**
 * The transceiver provides a convenient way to decorate an instance with receive and transmit capabilities.
 * It can (and this is encouraged) be used with the {@link Broker} instance.
 * The naming thing is not part of the Transeiver's functionality, but may be useful while debugging.
 * This class can be used for subclassing or as a "has-a"-relation, as it is possible to set
 * an arbitrary {@link Callback } listener.
 *
 */
public class Transceiver {
    private String mName="Transceiver";
    private static int ID=0;  

    private HandlerThread mHandlerThread;
    private Handler mHandler;  

    // delegates the messages, when no proprietary callback
    // is associated with the transeiver
    private class HandlerListener implements Callback{   

        @Override
        public boolean handleMessage(Message msg) {
            return Transceiver.this.handleMessage(msg);
        }  

    }  

    /**
     * Creates a transceiver with an automatically generated name
     */
    public Transceiver(){
        mName = new String("Transceiver(" + ++ID + ")");
        create(new HandlerListener());
    }  

    /**
     * Creates a transceiver with arbitrary name
     * @param name
     */
    public Transceiver(String name){
        ++ID;
        mName = name;
        create(new HandlerListener() );
    }  

    /**
     * Creates a transceiver with arbitrary name and an own listener
     * @param name a custom name
     * @param l your own listener
     */
    public Transceiver(String name, Callback l){
        ++ID;
        mName = name;
        create(l);
    }  

    private void create(Callback l){
        mHandlerThread = new HandlerThread(getName());
        mHandlerThread.start();
        Log.d(mName, "Waiting for looper...");
        // we need to wait (blocking) to get the looper instance
        while(!mHandlerThread.isAlive()) {};
        mHandler = new Handler(mHandlerThread.getLooper(), l);
        Log.d(mName, "Ready");
    }  

    /**
     * @return The name of this transceiver
     */
    public final String getName() { return mName; }  

    /**
     * @return Its internal handler
     */
    public final Handler getHandler() { return mHandler; }  

    /**
     * The callback method for received messages. You can override it, when deriving from Transceiver.
     * @param msg the message
     * @return true, if the message was handled.
     */
    public boolean handleMessage(Message msg) { return false; }
}
</pre>
<p><strong>按照物理顺序详细分析代码的作用</strong>：</p>
<ul style="text-align: left;">
<li><strong>mName</strong>和<strong>ID</strong>用来给线程添加一个可识别的标签；</li>
<li><strong>mHandlerThread</strong>和<strong>mHandler</strong>两个变量分别装载当前线程中<strong>HandlerThread</strong>和<strong>Handler</strong>的实例；</li>
<li><strong>HandlerListener</strong>类作为<strong>Callback</strong>的子类，响应Message信息的行为定义在  <strong>HandleMessage</strong> 方法中。在这个例子中实际的行为写在类中的一个独立方法中，然后再由<strong>HandleMessage</strong>去调用这个方法，这样做的目的为了让其子类可以重写基类（Transceiver)中<strong>HandleMessage</strong>的行为。</li>
<li>三种不同的构造函数。第一个可以根据系统自动分配线程标签，第二个是接受指定命名，前两种还有一个共同点是使用类中默认的<strong>handleMessage</strong>，第三个包含两个参数，一个是标签名称，另外一个用于自定义新的<strong>handlerMessage</strong>行为。</li>
<li>create方法是创建HandlerThread的核心部分，将<a target="_blank" href="http://developer.android.com/reference/javax/security/auth/callback/Callback.html" target="_blank">Callback</a>类型参数应用于HandlerThread的<a target="_blank" href="http://developer.android.com/reference/android/os/Looper.html" target="_blank">Looper</a>类中处理消息循环（接收信息并作出回应 &#8211; Looper class used to run a message loop for a thread.）。</li>
<li>getName和getHandler无需解释，一个是用于返回当前HandlerThread标签的方法，另外一个返回Handler实例。</li>
</ul>
<p>接下来分析“<span style="color: #008000;">玻璃球盒子</span>”。小时候经常将手中的玻璃球随意乱放，而且经常有丢失的情况发生，就是因为没有一个统一管理的方法。当创建了多个HandlerThread之后，有必要设置一个容器将它们合理的安置，以至于当需要的时候可以快速的通过标签找到想要索引的线程。<strong>下边先来看完整的源代码（保留原有英文注释）：</strong></p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
import java.util.ArrayList;
import android.os.Handler;
import android.os.Message;  

/**
 * The broker is a kind of repository for {@link Handler} instances. It provides a simple and very convenient mechanism to
 * establish communication between different handlers. Just subscribe a handler instance and use the returned address with
 * this Broker. This class is thread safe, of course.
 * Usage example:
 * <code>
 * this.MyCompAddr = Broker.instance.subscribe( new Handler() );
 * // or, when using transceiver
 * this.MyRendererAddr = Broker.instance.subscribe( new MyTransceiver("Renderer").getHandler() );
 * [...]
 * // how to send messages
 * Message m = Message.obtain();
 * m.what = 1; // could be an identifier or op-code or whatever you want
 * Bundle b= new Bundle(); // or use more complex (key,value)-pairs.
 * b.putString("data", "Any Data");
 * m.setData(b);
 * Broker.instance.post(this.MyRendererAddr, m);
 * </code>
 *
 */
public class Broker {  

    /**
     * The static instance.
     */
    public static Broker instance=new Broker();
    private ArrayList< Handler > mHandler;  

    private Broker()
    {
        mHandler = new ArrayList< Handler > ();
    }  

    /**
     * Subscribe a handler, so you can send messages easily to it.
     * Mind there is no check for doubled subscription.
     * @param h The handler
     * @return The "address" for the handler
     * @see {@link unsubscribe() }
     */
    public synchronized int subscribe(Handler h){
        ArrayList< Handler > hl=mHandler;
        hl.add(h);
        return hl.size()-1;
    }  

    /**
     * Unsubscribes a handler. Invalid addresses are ignored
     * @param address
     */
    public synchronized void unsubscribe(int address){
        if(isAddressValid(address))
            mHandler.remove(address);
    }  

    protected synchronized final boolean isAddressValid(int address){
        ArrayList< Handler > h=mHandler;
        return (!h.isEmpty() &#038;&#038; address >= 0 &#038;&#038; address < h.size() );
    }  

    /**
     * Post a message to addressed receiver.
     * @param address
     * @param m
     * @return true, if address exists, i.e. message could be delivered
     */
    public synchronized boolean post(int address, Message m){
        ArrayList< Handler > h=mHandler;
        if(!isAddressValid(address))
            return false;  

        h.get(address).sendMessage(Message.obtain(m));
        return true;  

    }  

    /**
     * Sends a message to all connected handler
     * @param m The message
     * @return The number of notified handler, e.g. send messages.
     */
    public synchronized int broadcast(Message m)    {
        ArrayList< Handler > h=mHandler;
        int n=h.size();
        for(int i=0; i < n; ++i)
        {
            h.get(i).sendMessage(Message.obtain(m));
        }
        return n;
    }
}
</pre>
<p><strong>按照物理顺序详细分析代码的作用：</strong></p>
<ul style="text-align: left;">
<li><strong>instance：</strong>在Broker类中创建一个静态实例，可以在其它方法中直接调用其资源。</li>
<li><strong>mHandler：</strong>这个是用来存放Handler实例的数组，也是这个容器的核心，后边所创建的方法都针对这个数组来操作。</li>
<li><strong>Broker(): </strong>类内部的构造函数。它为mHandler建立一个ArrayList&lt;Handler&gt;数组实例。</li>
<li><strong>subscribe()</strong>：相当于数组的"Add"方法，返回值是当前所添加的Handler在<strong>mHandler</strong>数组中的“座位号”。</li>
<li><strong>unsubscribe():</strong> 相当于数组的"Remove"方法，传递一个“座位号”可以将它的实例从<strong>mHandler</strong>中移除。</li>
<li><span><span><strong>isAddressValid():</strong> 验证“座位号”的合法性，其原理仅仅是判断这个号是否超出了当前数组中子集的数量或者是否为不小于0的整数。</span></span></li>
<li><strong>post():</strong> 根据“座位号”将<a target="_blank" href="http://developer.android.com/reference/android/os/Message.html" target="_blank">Message</a>发送给这个指定的线程。</li>
<li><strong>broadcast():</strong> 可以根据这个意思理解为拿个大喇叭对当前容器内的所有线程实例广播。如果说post是k98步枪，那么这个可以算得上是MG42了。</li>
</ul>
<p>以上就是对线程间通讯方法的简单介绍，下边是一些更加实际的例子，可以帮助大家理解如何在你的程序中调用上边的类。</p>
<p><strong>例子一：</strong></p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
/**
* a place where I store my addresses.
* Read-only access to once set addresses is thread-safe!
*/
public class AddressPool {
    public static int Subsystem1,Subsystem2,MyActivity;
}  

// #extending Transceiver (is-a-relation) # 

public class Subsystem2 extends Transceiver {
    public final static String TAG="Subsystem2";
    public final static int WHAT = 3862; // a magic number  

    public boolean handleMessage(Message m){  

        switch(m.what){
        case Subsystem1.WHAT:
            Log.i(TAG,"Received message from " + Subsystem1.TAG);
            // attention: when answering we need a new message
            Message msg= Message.obtain(m);
            Broker.instance.post(AddressPool.Subsystem1, msg);
            break;
        case MyActivity.WHAT:
            Log.i(TAG,"Received message from " + MyActivity.TAG );
            break;
        }
        return true;
    }
}
</pre>
<p><strong>例子二：</strong></p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
// #wrapping/using Transceiver (has-a-relation) # 

package com.o1.android;  

import java.util.Timer;
import java.util.TimerTask;  

import com.o1.android.util.message.Broker;
import com.o1.android.util.message.Transceiver;  

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Handler.Callback;
import android.util.Log;  

public class Subsystem1 extends TimerTask implements Callback{
    public final static String TAG="Subsystem1";
    public final static int WHAT = 175; // any identifier
    private Transceiver mTransceiver;
    private int mMyAddress=-1;
    private Timer mTimer;  

    public Subsystem1(){
        mTransceiver = new Transceiver(TAG, this);
        mTimer = new Timer("SubsystemTimer");  

    }  

    public void onStart(){
        mMyAddress = Broker.instance.subscribe(mTransceiver.getHandler());
        // we use a timer to asynchronously post messages
        mTimer.schedule(this, 0, 125);
    }  

    public void onQuit(){
        mTimer.cancel();
        Broker.instance.unsubscribe(mMyAddress);
    }  

    public final int getBrokerAddress() { return mMyAddress; }  

    @Override
    public boolean handleMessage(Message m) {
        switch(m.what){
        case Subsystem2.WHAT:
            Log.i(TAG,"Received message from " + Subsystem2.TAG);
            break;
        case MyActivity.WHAT:
            Log.i(TAG,"Received message from " + MyActivity.TAG);
            break;
        }
        // immediate response/delegate with a copy of our message
        Broker.instance.post(AddressPool.MyActivity, Message.obtain(m));
        return true;
    }  

    @Override
    public void run() {
        Message m= new Message();
        m.what=WHAT;
        Broker.instance.post(AddressPool.MyActivity, m);
    }
}
</pre>
<p><strong>例子三：</strong></p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
// #connecting activities # 

public class MyActivity extends Activity implements Callback {  

     private Subsystem1 mSubsystem1;
     //... other member fields  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        /*
        * We have different types of transceiver implementations.
        * One as "has" (subsystem1) and the other as "is"-relation.
        */
        mSubsystem1 = new Subsystem1();
        AddressPool.Subsystem2 = Broker.instance.subscribe(new Subsystem2().getHandler());
        // additionally, we can use activities (or other components with loopers)
        // mind that our activity implements Callback
        AddressPool.MyActivity = Broker.instance.subscribe(new Handler(this));
        // ... your stuff, e.g. a button that triggers messages  

    }   

    @Override
    public void onStart(){
        super.onStart();
        mSubsystem1.onStart();
        AddressPool.Subsystem1 = mSubsystem1.getBrokerAddress();
    }  

    @Override
    public void onDestroy(){
        super.onDestroy();
        mSubsystem1.onQuit();
    }  

    @Override
    public boolean handleMessage(Message msg) {
       // handle your messages here
    }
</pre>
<p><a target="_blank" href="http://www.androidsnippets.org/snippets/41/" target="_blank">查看原文 AndroidSnippets.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.androidres.com/index.php/2009/05/21/android-communicating-among-multi-threads/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>简单了解Handler的使用方法</title>
		<link>http://www.androidres.com/index.php/2009/04/07/android-handler-tutorials/</link>
		<comments>http://www.androidres.com/index.php/2009/04/07/android-handler-tutorials/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 08:55:02 +0000</pubDate>
		<dc:creator>Edgar Sun</dc:creator>
				<category><![CDATA[Resource]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Handler]]></category>

		<guid isPermaLink="false">http://www.androidres.com/?p=330</guid>
		<description><![CDATA[写过JavaScript或者ActionScript的开发者，对于setInterval的用法会非常了解。那么在Android中如何实现setInterval的方法呢？其中有两种方法可以实现类似的功能，其中一个是在线程中调用Handler方法，另外一个是应用Timer。如果想了解更全面的用法，可以查看SDK Samples中一个叫做&#8221;Snake.java&#8221;源码，可以通过它了解一些更复杂的用法。
首先引用Handler在实际应用中的一个简单的例子：

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class Main extends Activity  {
   private TextView txtStatus;
   private RefreshHandler mRedrawHandler = new RefreshHandler();

   class RefreshHandler extends Handler {
      @Override
      public void handleMessage(Message msg) {
       [...]]]></description>
			<content:encoded><![CDATA[<p>写过JavaScript或者ActionScript的开发者，对于setInterval的用法会非常了解。那么在Android中如何实现setInterval的方法呢？<span id="more-330"></span>其中有两种方法可以实现类似的功能，其中一个是在线程中调用Handler方法，另外一个是应用Timer。如果想了解更全面的用法，可以查看SDK Samples中一个叫做&#8221;Snake.java&#8221;源码，可以通过它了解一些更复杂的用法。<br />
首先引用Handler在实际应用中的一个简单的例子：</p>
<pre class="brush: java; smart-tabs: true;toolbar: false">
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class Main extends Activity  {
   private TextView txtStatus;
   private RefreshHandler mRedrawHandler = new RefreshHandler();

   class RefreshHandler extends Handler {
      @Override
      public void handleMessage(Message msg) {
         Main.this.updateUI();
      }

      public void sleep(long delayMillis) {
         this.removeMessages(0);
         sendMessageDelayed(obtainMessage(0), delayMillis);
      }
   };

   private void updateUI(){
      int currentInt = Integer.parseInt((String) txtStatus.getText()) + 10;
      if(currentInt <= 100){
         mRedrawHandler.sleep(1000);
         txtStatus.setText(String.valueOf(currentInt));
      }
   }

   @Override
   public void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      setContentView(R.layout.main);
      this.txtStatus = (TextView) this.findViewById(R.id.txtStatus);
      updateUI();
   }
}
</pre>
<p><strong>简短说明(Quick explanation):</strong><br />
创建一个继承Handler的Class，一定要重新实现(Override)类中的handleMessage方法 （ Subclasses must implement this to receive messages. ）。然后再声明Sleep方法，其目的是调用延迟发送Message的方法 sendMessageDelayed。updateUI作为核心方法，修改TextView中的数值。其本身包含有调用Sleep的方法和一个终止Handler的判断条件。<br />
建议在看源代码时，实际创建一个工程来测试这段简单的代码，可以更容易了解Handler的执行过程。</p>
<p>Layout 源码：</p>
<pre lang="xml" line="n">
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
	android:id="@+id/txtSatus"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="0"
    />
</LinearLayout>
</pre>
<p>官方文档：<a target="_blank" href="http://developer.android.com/reference/android/os/Handler.html">Handler</a></p>
<p><a target="_blank" href="http://almondmendoza.com/2009/01/05/using-handler-in-android/">Via Almond mendoza</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.androidres.com/index.php/2009/04/07/android-handler-tutorials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
