处理程序类如何在Android中工作

我是新来的android和正在阅读官方安卓网站上的演示应用程序。 我遇到了一个名为postDelayed(Runnable r, long milliseconds)Handler类的方法。

任何人都可以解释一下这个方法吗?

Solutions Collecting From Web of "处理程序类如何在Android中工作"

你可以看到文档 。

但要理解文档,首先应该理解几个概念: 消息,消息队列,处理程序和循环 ,以及它们之间的关系 。

下面说明Looper如何工作,它显示了Looper是一个线程本地对象及其与MessageQueue的关系:

 class Looper{ public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } msg.target.dispatchMessage(msg); msg.recycle(); } } } } 

几点评论:

Looper是一个线程本地对象,每个线程都有一个活套。 每个活套与一个消息队列相关联。 活套连续从队列中获取messagese(“tasks”,“commands”或任何你喜欢调用它们的东西),并将消息发送到它的目标,它是一个处理这个消息的处理程序(例如,通过callback一个包含消息)。 当队列中没有消息时,线程会阻塞,直到有新消息。 要停止一个Looper,你必须调用quit()(它可能不会立即停止循环,而是设置一个私有标志,定期从循环中检查,通知它停止)。

Android框架提供了Handler类来简化事物。 当你创build一个Handler实例时,(默认情况下)绑定到已经附加到当前线程的Looper。 (处理程序知道Looper要附加到什么地方,因为我们之前调用了prepare()方法,它将一个对Looper的引用存储在一个ThreadLocal中。)

使用Handler,你可以调用post()来“把消息放入线程的消息队列”(可以这么说)。 处理程序将负责所有的IdleHandlercallback的东西,并确保您的发布Runnable执行。 (如果你延迟发布,它也可能检查时间是否已经正确。)

以下代码显示了我们使用它们的典型方法。

 class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } 

}

处理程序广泛用于Android服务。 Android支持应用程序间通信。 通常,当我们实现一个不需要处理multithreading的服务时,我们实现了一个Handler,它接收来自客户端的每个调用的callback。 然后创build一个Messenger对象(对Handler的引用),它是一个Binder对象,并在绑定此服务时将此对象返回给客户端。 所以客户端可以使用这个Messenger将消息(通过Looper发送到线程本地队列,发送给处理程序)发送到这个服务,并在处理程序中处理它们。 代码示例附后:

 public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } final Messenger mMessenger = new Messenger(new IncomingHandler()); @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } } 

postDelayed (Runnable r, long delayMillis)

使Runnable r被添加到消息队列中,在指定的时间过后运行。 runnable将在该处理程序所连接的线程上运行。

  • Runnable表示可以执行的命令。

  • delayMillis表示应该执行的时间。

基本上,它延迟特定时间段( delayMillis )的命令(某些代码)的执行,以便在指定的时间之后执行该命令。

 public class ApiHandler { public static final String BASE_URL = "http://xxx.yyy/xx/"; private static final long HTTP_TIMEOUT = TimeUnit.SECONDS.toMillis(120); private static Webservices apiService; public static Webservices getApiService() { if (apiService == null) { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); okHttpClient.setWriteTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); okHttpClient.setReadTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS); RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(BASE_URL) .setClient(new OkClient(okHttpClient)) .setConverter(new GsonConverter(new Gson())) .build(); apiService = restAdapter.create(Webservices.class); /*RestAdapter.Builder builder = new RestAdapter.Builder(); builder.setConverter(new StringConverter()) .setEndpoint(BASE_URL) .setClient(new OkClient(new OkHttpClient())) .setLogLevel(RestAdapter.LogLevel.NONE); RestAdapter adapter = builder.build(); apiService = adapter.create(Webservices.class);*/ return apiService; } else { return apiService; } } }