我是Android新手,正在官方Android网站上阅读演示应用程序。我遇到了一个名为Handler
的{{1}}类的方法。
有人可以解释这种方法的作用吗?
答案 0 :(得分:51)
您可以看到documentation。
但要了解文档,您应首先了解几个概念:Message, Message Queue, Handler and Looper和他们的relationship。
下面说明了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是一个线程本地对象,每个线程都有一个looper。每个循环器都与一个消息队列相关联。 looper不断地从队列中获取消息(“任务”,“命令”或任何你喜欢称之为的命令),并将消息发送到其目标,该目标是处理该消息的处理程序(例如,通过回调包含在其中的Runnable)消息)。当队列中没有剩余消息时,线程会阻塞,直到有新消息。要停止Looper,你必须在它上面调用quit()(这可能不会立即停止循环,而是设置一个私有标志,从循环中定期检查,表示它停止)。
Android框架提供了Handler类来简化操作。创建Handler实例时,它(默认情况下)绑定到已连接到当前线程的Looper。 (Handler知道Looper要附加什么,因为我们之前调用了prepare(),它在ThreadLocal中存储了对Looper的引用。)
使用Handler,你可以调用post()来“将消息放入线程的消息队列”(可以这么说)。处理程序将处理所有IdleHandler回调内容并确保已发布已发布的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();
}
}
Handler广泛用于Android服务。 Android支持跨应用程序通信。通常,当我们实现一个不需要处理多线程的服务时,我们实现了一个Handler,它接收来自客户端的每个调用的回调。然后创建一个Messenger对象(对Handler的引用),它是一个Binder对象,并在绑定此服务时将此对象返回给客户端。因此,客户端可以使用此Messenger将消息(进入线程本地队列,通过Looper发送给处理程序)发送到此服务,并在Handler中处理它们。附上代码示例:
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();
}
}
答案 1 :(得分:6)
postDelayed (Runnable r, long delayMillis)
使Runnable r
添加到消息队列中,在指定的时间量过后运行。 runnable
将在此处理程序所附加的线程上运行。
Runnable 表示可以执行的命令。
delayMillis 表示应该执行的时间。
基本上,它会在特定时间段(delayMillis
)延迟执行命令(某些代码可能),以便在指定时间后执行命令。
答案 2 :(得分:-1)
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;
}
}
}