Android游戏开发之Thread与Handler执行多线程
游戏开发与软件开发多线程的重要性
如果程序主线程被阻塞超过5秒,系统会提示“应用程序无响应” 这就是ANR 。 ANR的全称是Application Not Responding,使用多线程可以避免ANR。但是这里要注意一下不要为了避免ANR而过多的使用多线程,除非万不得已的情况。 比如访问网络服务端返回的过慢、数据过多导致滑动屏幕不流畅、或者I/O读取过大的资源等等。这里可以开启一个新线程来处理这些耗时的操作。 如果过多使用多线程会出现数据同步的问题须要程序员去处理,所以使用多线程的时候尽量保持它的独立不会被其它线程干预。java语言提供了一个线程锁的概念 synchronized 可以添加对象锁与方法锁专门避免多线程同时访问一个方法或者一个对象导致的问题,有兴趣的朋友可以去看看这里我不罗嗦啦 。
Thread与Handler执行多线程
Handler主要用于程序主线程与我们自己创建的线程进行通信。在这个例子中点击按钮后创建一个新的线程去循环的加载100张图片每加载完一张图片在Thread中使用Handler发送消息通知UI线程更新显示,直到加在完毕通知UI显示加载完成一共耗时多少秒。可见Handler的重要性它就是主线程与我们自己创建的线程的桥梁啊~~~
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class SingleActivity extends Activity {
/**读取进度**/
public final static int LOAD_PROGRESS = 0;
/**标志读取进度结束**/
public final static int LOAD_COMPLETE = 1;
/** 开始加载100张图片按钮 **/
Button mButton = null;
/** 显示内容 **/
TextView mTextView = null;
/** 加载图片前的时间 **/
Long mLoadStatr = 0L;
/** 加载图片后的时间 **/
Long mLoadEnd = 0L;
Context mContext = null;
//接收传递过来的信息
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOAD_PROGRESS:
mTextView.setText("当前读取到第" + msg.arg1 + "张图片");
break;
case LOAD_COMPLETE:
mTextView.setText("读取结束一共耗时" + msg.arg1 + "毫秒");
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.single);
mContext = this;
/** 拿到button 与 TextView 对象 **/
mButton = (Button) findViewById(R.id.button0);
mTextView = (TextView) findViewById(R.id.textView0);
mTextView.setText("点击按钮开始更新时间");
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//开始读取图片
LoadImage();
}
});
super.onCreate(savedInstanceState);
}
public void LoadImage() {
new Thread() {
@Override
public void run() {
//得到加载图片开始的时间
mLoadStatr = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
// 这里循环加载图片100遍
ReadBitMap(mContext, R.drawable.bg);
// 每读取完一张图片将进度甩给handler
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 = i + 1;
handler.sendMessage(msg);
}
//得到加载图片结束的时间
mLoadEnd = System.currentTimeMillis();
//100张图片加载完成
Message msg = new Message();
msg.what = LOAD_COMPLETE;
msg.arg1 = (int) (mLoadEnd - mLoadStatr);
handler.sendMessage(msg);
}
}.start();
}
/**
* 读取本地资源的图片
*
* @param context
* @param resId
* @return
*/
public Bitmap ReadBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
}