- 浏览: 39813 次
-
文章分类
- 全部博客 (37)
- java (37)
- [文摘20081112]经典语录 (1)
- php+mysql预查询prepare 与普通查询的性能对比 (1)
- Android采用SharedPreferences保存用户登录信息 (1)
- 找bug记(2) (1)
- 细节优化提升资源利用率 (1)
- java(j2se)学习笔记----类注释文档编写方法? (1)
- 如何查看Class文件编译的JDK版本 (1)
- 验证码显示不了,报Could not initialize class sun.awt.X11GraphicsEnvironment (1)
- Android使用KSOAP2调用WebService及正确导入jar包的问题 (1)
- The content of the adapter has changed but ListView did not receive a notification. (1)
- 很想写些CMMI的东西 (1)
- JPA & Hibernate 注解 (1)
- Java反编译工具――Jode (1)
- Eclipse3.0.0插件安装解决方法 (1)
- SVG简介及相关工具 (1)
- 开始在这个BLOG里放一部分MapXtreme2004相关代码 (1)
- 支持.NET环境的GIS开发工具MapXtreme2004 (1)
- 将DAT格式视频文件转换成ASF和WMV格式视频文件 (1)
- 《漫谈设计模式》一书终于出版了 (1)
- 一位程序员的一个LBS应用的想法 (1)
- 一刷网络投票的小程序 (1)
- 面试字符串处理之单词翻转 (1)
- rails 上载xls文件 (1)
- 如何获得Java项目文件所在的相对路径 (1)
- 学习FlexViewer(一)——事件和框架 (1)
- Android开发之消息处理机制(二)——消息循环 (1)
- JAVA操作——获取文件扩展名,去掉文件扩展名 (1)
- freemarker 读取session 值 (1)
- xfire 使用用户名/密码进行身份认证 (1)
- java中的图片处理 (1)
- HTC Touch HD2/LEO/T8585刷机教程 进三色屏 (1)
- js性能问题 (1)
- js 事件收集 (1)
最新评论
-
Glorin:
非常感谢你,让我的问题能够得以解决。
验证码显示不了,报Could not initialize class sun.awt.X11GraphicsEnvironment -
thzthbthy:
/*
* Java文件操作 获取文件扩展名
*
...
JAVA操作——获取文件扩展名,去掉文件扩展名 -
jyjava:
你debug调试,应该很快会定位到的
找bug记(2) -
xuehua1987:
上面的方法返回值是void ,怎么可以返回你取到的连接???? ...
找bug记(2)
<h1>Android开发之消息处理机制(二)——消息循环</h1>
/*
* Android开发之消息处理机制(二)——消息循环
* 北京Android俱乐部群:167839253
* Created on: 2011-9-1
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
先介绍一下如何在Android应用程序中使用后台线程和UI线程。
创建Android友好的后台线程时,最灵活的方式就是创建Handler子类的一个实例。每个Activity仅需要一个Handler对象,而且不需要手动注册他。
后台线程可以与Handler通讯,Handler将在Activity的UI线程上执行自己所有的工作。这一点非常重要。因为UI的更改,只能发生在Activity的UI线程上。
有两种与Handler通信的方式:消息和Runnable对象。
关于消息:
要向Handler发送一个Message,首先调用obtainMessage()从池中获取Message对象。obtainMessage()对象有许多特点,允许创建空的Message对象或填充了消息标示符和参数的对象。需要的Handler处理过程越复杂,就越需要将数据放在Message中,以帮助Handler区分不同的事件。
然后可以通过消息队列将Message发送给Handler,此时需要使用sendMessage…()系列方法中的一个方法。
sendMessage();立即将消息放在队列中。
sendMessageAtFrontOfQueue();立即将消息放在队列中,并将其放在消息队列的最前面,这样该消息就会具有比所有其他消息更高的优先级。
sendMessageAtTime();在规定的时间将消息放在队列中,这个时间用ms表示,基于系统正常工作时间。(SystemClock.uptimeMillis())
sendMessageDelayed();在一段延迟之后将消息放在队列中,延迟用ms表示。
要处理这些消息,Handler需要实现handleMessage(),将使用出现在消息队列中的每个消息来调用handleMessage()。此处Handler可以根据需要更新UI。但是,它仍然应该迅速完成此工作,因为在它完成之前,其他UI工作会暂停。
关于Runnable :
如果不愿意使用Message对象,也可以将Runnable对象传递给Handler,Handler将在ActivityUI线程上运行这些Runnable对象。Handler提供了一组post…()方法来传入Runnable对象供最终处理。
对Android的消息循环机制的理解,可以仿照Windows消息循环的机制进行。
每个Handler都会和一个线程和线程的message queue关联起来,此时你可以传递messages 和 runnable对象到message queue中。后面可以从message queue中拿出该对象并且执行。Handler, Message queue这两个对象之间的交互,就涉及到了Looper这个东西。
关于Handler,Looper,Message Queue三者之间的关系,如下图所示:
<img src="http://hi.csdn.net/attachment/201109/2/0_1314984151G3pn.gif" alt="">
Handler有很多构造函数
Handler在无参数的构造方法中调用Looper.myLooper()方法,里面就是从当前线程里面获取一个Looper的同时一并初始化MessageQueue,并且从中得到looper的MessageQueue。可以看出Handler就是Looper和MessageQueue的管理者和调度者。
其中最重要的是sendMessageAtTime方法,当你往Handler中发送Message消息的时候,从代码看出他自己并不去处理Message,而是交给了MessageQueue,由queue.enqueueMessage来处理。
Looper代码中有一个prepare()方法,通过ThreadLocal实现一个线程只有一个Looper。
Handler的消息发送
Handler是一个核心,负责message的创建,获得,处理。Handler的sendMessage()方法最终其实就是调用了queue.enqueueMessage(msg, uptimeMillis);把消息放入message queue中。Looper通过Looper.loop()检测到有消息并将消息广播后,Handler又负责接收到此消息并调用handleMessage进行处理接下来的事情。Message的创建一般都是通过如下代码建立的,把Handler传进去。
public final Message obtainMessage()
{
return Message.obtain(this);
}
这种工作方式如下图所示:
<img src="http://hi.csdn.net/attachment/201109/2/0_13149841835PgG.gif" alt="">
Message在里面是一个链表的结构。在这个方法中,会首先去MessagePool(消息回收站)去找Message,如果有被回收的Message,则会将这个Message取出来进行再利用。如果没有被回收的,这时系统才会真正new一个Message对象出来当然MessagePool不是无限大的,它最多只能保存十条回收的消息,多出来的就直接删除了。
至此,我们看到,一个Message经由Handler创建、发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler进行处理。而绕的这一圈,也正好帮助我们将同步操作变成了异步操作。
在主线程(UI线程)里,如果创建Handler时不传入Looper对象,那么将直接使用主线程(UI线程)的Looper对象(系统已经帮我们创建了);在其它线程里,如果创建Handler时不传入Looper对象,那么,这个Handler将不能接收处理消息。在创建Handler之前,为该线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop),抽取Message,这样,Handler才能正常工作。
因此,Handler处理消息总是在创建Handler的线程里运行。
下面根据上述理论知识,来举几个例子:
例1:
在UI线程中调用Handler的Post方法。代码如下:
<textarea readonly name="code" class="java">/*
* Android开发之消息处理机制(二)——消息循环
* MessageCircle.java
* Created on: 2011-9-2
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
package blueeagle.com;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
public class MessageCircle extends Activity {
/** Called when the activity is first created. */
private Handler myHandler = new Handler();
private Runnable myRunnable = new Runnable(){
@Override
public void run(){
try{
Thread.sleep(1000);
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Current Runnable Thread ID:"+Thread.currentThread().getId());
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Current Activity Thread ID:"+Thread.currentThread().getId());
myHandler.post(myRunnable);
}
}
</textarea><br>
程序运行结果如下图:
<img src="http://hi.csdn.net/attachment/201109/2/0_1314984234T5O3.gif" alt="">
在这个程序中,我们New了一个没有参数的Handler对象myHandler,这个myHandler自动与当前运行程序相关联,也就是说,这个myHandler将与当前运行的线程使用同一个消息队列,并且可以处理该队列中的消息。
在程序代码中,这个myHandler向消息队列中post了一个myRunnable对象。在myRunnable的run方法中,打印当前线程的ID。由结果得知,我们New出来的这个myHandler是把消息或者Runnable对象送到当前的线程中的。这里我们没有调用线程的start()函数,因此也就不会去创建一个新的线程。而是在原有线程的内部,直接调用run()方法。因此输出的ID是相同的。
那么如何创建新的线程呢?在Android开发之消息处理机制(一)中已经知道如何去创建一个新的线程,这里继续举一个例子来进行比较说明。
例2:
首先需要创建一个线程,这个线程可以是自己创建的线程,也可以是HandlerThread,这个线程需要继承于Thread类或者实现Runnable接口。其次需要有一个Handler,这个Handler可以是Handler也可以继承于Handler并且需要有一个有Looper参数的构造函数。然后就可以进行消息的分发执行了。
具体示例代码如下:
<textarea readonly name="code" class="java">/*
* Android开发之消息处理机制(二)——消息循环
* MessageCircle.java
* Created on: 2011-9-2
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
package blueeagle.com;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;
public class MessageCircle extends Activity {
public class MyOwnThread extends Thread{
int sleepSpan = 2000;//休眠时间
boolean flag;// 线程执行标志位
//----------------------------------//
//构造方法,初始化类的主要成员变量
public MyOwnThread(){
this.flag = true;
}
//----------------------------------//
//方法,线程执行方法
@Override
public void run(){
TextView myTextView = (TextView)findViewById(R.id.mytextview);
Looper.prepare();
int i = 1;
while(flag){
try{
Thread.sleep(sleepSpan);//休眠一段时间
System.out.println("Current MyOwnThread Thread ID: "+Thread.currentThread().getId());
myTextView.setText(i);
i++;
}
catch(Exception e){
e.printStackTrace();//捕获异常并打印
}
}
Looper.loop();
}
}
public class MyHandler extends Handler{
public MyHandler(){}
public MyHandler(Looper looper){
super(looper);
}
@Override
public void handleMessage(Message msg){
System.out.println("Current MyHandle Thread ID: "+Thread.currentThread().getId());
TextView myTextView = (TextView)findViewById(R.id.mytextview);
int i = 1;
while(true){
try{
Thread.sleep(1000);//休眠一段时间
System.out.println("Current MyHandle Thread ID: "+Thread.currentThread().getId());
myTextView.setText("i");
i++;
}
catch(Exception e){
e.printStackTrace();//捕获异常并打印
}
}
}
}
/** Called when the activity is first created. */
private MyHandler myHandler = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Current Activity Thread ID:"+Thread.currentThread().getId());
//myHandler.post(myRunnable);
HandlerThread myThread = new HandlerThread("myThread");//生成一个HandlerThread对象,使用Looper来处理消息队列。
myThread.start();//启动这个线程
myHandler = new MyHandler(myThread.getLooper());//将一个线程绑定到myHandler这个对象上。
Message msg = myHandler.obtainMessage();//从myHandler这个对象中获取消息
msg.sendToTarget();//将msg对象发送给目标的Handler
//下面制造一个自己的线程
MyOwnThread myOwnThread = new MyOwnThread();
myOwnThread.start();
}
}
</textarea><br>
关于线程更新UI的方法,在(一)中已经说过。下面利用一个示例将消息循环过程进行展示,进而实现音乐播放,UI线程中更新歌词的例子来说明消息处理机制。例子较简单,没有实现歌词同步等内容。只是为了更深刻的理解线程运行情况。
按照上述理论:代码如下:
<textarea readonly name="code" class="java">/*
* Android开发之消息处理机制(二)——消息循环
* MusicPlayer.java
* Created on: 2011-9-3
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
package blueeagle.com;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MusicPlayer extends Activity {
/** Called when the activity is first created. */
Button myButton;
TextView myTextView;
private UIUpdateThread myUpdateThread = new UIUpdateThread(); //定义一个自己的UI更新的线程类
MyHandler mHandler = new MyHandler();//定义自己的一个Handler类
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myButton = (Button)findViewById(R.id.myButton);
myTextView = (TextView)findViewById(R.id.myTextView);
myButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("主线程运行ID:"+Thread.currentThread().getId());
new Thread(myUpdateThread).start();//起一个自己定义的线程
}
});
}
class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法
public MyHandler(){
}
public MyHandler(Looper l){
super(l);
}
@Override
public void handleMessage(Message msg) {//执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出
myTextView.setText(msg.toString());
System.out.println("Current Handler Thread ID:"+Thread.currentThread().getId());
}
}//该线程将会在单独的线程中运行
class UIUpdateThread implements Runnable {
int i=1;
public void run() {
while (i<11) {
Message msg = mHandler.obtainMessage();
mHandler.sendMessage(msg);
System.out.println("新线程运行ID:"+Thread.currentThread().getId());
i++;
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
</textarea>关于简单的音乐播放的源码如下:
<textarea readonly name="code" class="java">/*
* Android开发之消息处理机制(二)——消息循环
* MusicPlayer.java
* Created on: 2011-9-3
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
package blueeagle.com;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MusicPlayer extends Activity {
/** Called when the activity is first created. */
private MediaPlayer mp;
Button myButton;
TextView myTextView;
private UIUpdateThread myUpdateThread = new UIUpdateThread(); //定义一个自己的UI更新的线程类
MyHandler mHandler = new MyHandler();//定义自己的一个Handler类
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myButton = (Button)findViewById(R.id.myButton);
myTextView = (TextView)findViewById(R.id.myTextView);
myButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mp = MediaPlayer.create(MusicPlayer.this, R.raw.yinweiaiqing);
mp.start();
System.out.println("主线程运行ID:"+Thread.currentThread().getId());
new Thread(myUpdateThread).start();
}
});
}
class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法
public MyHandler(){
}
public MyHandler(Looper l){
super(l);
}
@Override
public void handleMessage(Message msg) {//执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出
myTextView.setText(msg.obj.toString());
System.out.println("Current Handler Thread ID:"+Thread.currentThread().getId());
}
}//该线程将会在单独的线程中运行
class UIUpdateThread implements Runnable {
int i = 0;
String myString[] = {
"这是一个实时播放的线程操作... ...",
"[00:08.79]《因为爱情》",
"[00:19.46]E 给你一张过去的CD",
"[00:28.68]听听那时我们的爱情",
"[00:34.12]有时会突然忘了",
"[00:37.48]我还在爱著你",
"[00:44.98]F 再唱不出那样的歌曲",
"[00:50.48]听到都会红著脸躲避",
"[00:55.83]虽然会经常忘了",
"[00:59.33]我依然爱著你",
"[01:05.49]F 因为爱情 不会轻易悲伤",
"[01:05.49]F 因为爱情 不会轻易悲伤",
"[01:12.09]E 所以一切都是幸福的模样",
"[01:17.24]F 因为爱情 简单的生长",
"[01:22.24]E 依然随时可以为你疯狂",
"[01:27.21]F 因为爱情 怎麼会有沧桑",
"[01:34.30]E 所以我们还是年轻的模样",
"[01:38.90]F 因为爱情 在那个地方",
"[01:44.32]E 依然还有人在那里游荡",
"[01:48.91]E&F 人来人往",
"[02:11.57]F 再唱不出那样的歌曲",
"[02:17.70]听到都会红著脸躲避",
"[02:23.14]虽然会经常忘了",
"[02:26.26]E&F 我依然爱著你",
"[02:32.60]F 因为爱情 不会轻易悲伤",
"[02:39.22]E 所以一切都是幸福的模样",
"[02:44.98]F 因为爱情 简单的生长",
"[02:49.36]E 依然随时可以为你疯狂",
"[02:54.38]F 因为爱情 怎麼会有沧桑",
"[03:00.94]E 所以我们还是年轻的模样",
"[03:06.04]F 因为爱情 在那个地方",
"[03:11.63]E 依然还有人在那里游荡",
"[03:17.04]E&F 人来人往",
"[03:21.98]E 给你一张过去的CD",
"[03:28.58]听听那时我们的爱情",
"[03:33.48]F 有时会突然忘了",
"[03:36.94]E&F 我还在爱著你"};
public void run() {
while (mp.isPlaying()) {
Message msg = mHandler.obtainMessage(1, 1, 1, myString[i]);
mHandler.sendMessage(msg);
System.out.println("新线程运行ID:"+Thread.currentThread().getId());
try {
Thread.sleep(4000);
i++;
if(i == myString.length){
i=myString.length-1;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
</textarea>综上,基本了解了Android下的关于线程,消息循环的一些概念,还需要深入了解Looper如何运用在程序中等。
<br>
发表评论
-
js 事件收集
2012-02-08 13:18 582一般事件 事件 浏 ... -
js性能问题
2012-02-08 13:13 788随着web应用的复杂度日渐提高,JavaScript代 ... -
HTC Touch HD2/LEO/T8585刷机教程 进三色屏
2012-02-07 15:53 1092[size=14px; line-height: 21 ... -
java中的图片处理
2012-02-04 12:44 796附件中的文件包括: 1.图片的压缩 2.处理圆角图片 ... -
xfire 使用用户名/密码进行身份认证
2012-02-03 16:59 1207对SOAP报文进行身 ... -
freemarker 读取session 值
2012-02-03 08:25 2539<span style="font-f ... -
JAVA操作——获取文件扩展名,去掉文件扩展名
2012-01-31 14:08 2319<p> 昨天收邮件,得知要参加一个产品部的 ... -
学习FlexViewer(一)——事件和框架
2012-01-11 11:44 1238????? 上午做了关于FlexViewer的讲座,项 ... -
如何获得Java项目文件所在的相对路径
2011-12-28 15:08 2282[size=18px;]今天在开发中做一个java项 ... -
rails 上载xls文件
2011-12-21 12:14 1115?<span style="font- ... -
面试字符串处理之单词翻转
2011-12-21 11:34 909<p align="left&quo ... -
一刷网络投票的小程序
2011-12-20 11:44 1316最近看到网上一投 ... -
一位程序员的一个LBS应用的想法
2011-12-20 10:14 756最近状态不佳, ... -
《漫谈设计模式》一书终于出版了
2011-12-19 13:09 948<p class="MsoNor ... -
将DAT格式视频文件转换成ASF和WMV格式视频文件
2011-12-17 15:29 890以*.ASF和*.WMV为后缀名的视频文件,是微软针对 ... -
支持.NET环境的GIS开发工具MapXtreme2004
2011-12-16 16:12 702<font color="#ff000 ... -
开始在这个BLOG里放一部分MapXtreme2004相关代码
2011-12-15 14:38 564MapXtreme2004是嵌入到.NET环境中的地理 ... -
SVG简介及相关工具
2011-12-14 15:47 752<span style="" ... -
Eclipse3.0.0插件安装解决方法
2011-12-14 15:27 792<p class="MsoNorma ... -
Java反编译工具――Jode
2011-12-13 11:49 791</span> </span> ...
相关推荐
在Android开发过程中,消息处理机制是至关重要的部分,它涉及到应用程序如何管理、传递和响应各种事件。本篇文章将深入探讨Android中消息处理的核心组件——Looper、MessageQueue、Handler以及消息循环的工作原理。...
Content Provider 是 Android 系统中的一种机制,允许应用程序访问和操作系统中的数据。我们可以使用 Uri 对象来访问 APN 列表,例如: content://telephony/carriers // 取得全部 APN 列表 content://telephony/...
通常,我们会在自定义Thread的run方法中调用Looper.prepare()初始化消息循环,然后调用Looper.loop()开始无限循环地处理消息。 创建一个Handler实例,可以通过构造函数绑定到当前线程的Looper,或者在其他线程中...
在Android开发中,实现各种动画效果是提升用户体验的重要手段之一,而ImageView图片循环跑马灯效果就是其中之一。这种效果常用于展示广告轮播或者多张图片的连续展示,给人一种动态的视觉体验。在这个"Android源码...
此机制是Android应用开发中最常见的消息处理方式之一,它将消息传递的过程划分为三个主要阶段:消息循环的建立、消息的发送以及消息的处理。 #### 二、消息循环 消息循环是`Handler`机制的核心组成部分,负责接收...
在Android平台上,开发一款游戏需要深入理解Android操作系统的工作机制、图形渲染、用户交互以及性能优化等多个方面。"Android源码——游戏源码——忍者快跑.zip" 是一个包含了一个具体游戏项目源代码的压缩包,它为...
Android多线程机制是Android开发中非常重要的一部分,尤其是在处理耗时任务(如网络请求、大数据处理等)时,避免阻塞UI线程,保证应用程序的流畅性和响应性。本文将详细介绍Android多线程的基本原理及其核心组成...
在Android开发中,ImageView是我们常用的一个控件,用于显示单张或者多张图片。而"安卓Android源码——ImageView图片循环跑马灯的效果"则是一个关于如何实现ImageView中动态、循环展示图片效果的示例项目。这个项目...
让我们通过一个具体的案例来进一步阐述这一机制——假设我们在听歌时需要实现歌词同步功能。为了不影响用户界面的流畅性,我们可以创建一个新的线程专门处理歌词的滚动。在线程中,我们可以根据歌曲的播放时间...
开发者需要掌握Java或Kotlin语言,因为这两种语言是Android开发的主要编程语言。 二、JBox2D物理引擎介绍 Box2D是由Ernesto P. Adorio和 Erin Catto开发的一个强大的2D物理引擎,被广泛用于各种游戏开发。JBox2D是...
Android的异步处理机制,如Handler和Runnable,可能会用于实现游戏循环,确保游戏流畅运行而不阻塞主线程。 在源代码中,你会看到如何使用数组或者链表数据结构来表示蛇的身体部分,以及如何通过改变这些数据结构来...
在安卓Android平台上,开发一款游戏应用,如斗地主,涉及...以上就是基于安卓平台开发斗地主游戏的主要技术知识点,通过这份源码,开发者可以学习到实际项目中的Android开发流程、游戏逻辑设计以及性能优化等实践经验。
在安卓开发中,`Handler`、`Looper`和`MessageQueue`是三个核心组件,它们共同构成了Android消息处理机制,用于实现线程间的通信。这个压缩包“安卓Android源码——HandlerLooper2.rar”可能包含了关于这些组件的...
### Android高级开发面试题——Handler相关知识 #### 一、HandlerLooperMessage关系 **1. Handler、Looper与Message之间的关系** - **Handler**: 主要用于发送消息和处理消息。它作为一个桥梁,使得主线程和子...
在Android开发中,通常会用到以下几种`Handler`的用法: 1. **延时执行**:通过`sendMessageDelayed()`可以设置消息在未来的某个时间点被处理。 2. **取消消息**:`removeCallbacksAndMessages()`方法可以取消已经...
在安卓Android开发中,游戏引擎扮演着至关重要的角色,它们为开发者提供了丰富的功能,简化了2D游戏的构建过程。本文将深入探讨一个经典的游戏引擎——Anglev1.0,它是基于Android平台的2D游戏开发框架,对于理解...
这可能是一个关于LinuxIDC.com的介绍性文档,LinuxIDC.com可能是提供服务器托管或云计算服务的平台,与Android开发相关的部分可能涉及服务器配置、后台支持或者游戏的网络同步等技术。虽然这个文件与游戏音频处理...
《安卓Android源码——TheHardestGame》是一个深入探索安卓应用程序开发的专业项目,它涉及到Android系统的核心编程原理和游戏开发的实践应用。在这个项目中,我们可以学习到Android平台上的游戏开发流程,包括游戏...
2. **Android Studio**: 这是Google官方推荐的Android开发环境,集成了代码编辑、调试、构建和测试等功能。在这个项目中,开发者可能使用Android Studio进行代码编写和项目管理。 3. **布局设计**:贪吃蛇游戏需要...