线程再次start,崩?

中才德创 2012-06-04 07:02:19
程序运行后,surfaceCreated函数进入,m_thread.start()良好。

当程序最小化后,也就是按了手机的第二个按钮,surfaceDestroyed函数进入,m_thread.stop()良好。

再次最大化后,也就是按了手机的第二个按钮,选取该程序,m_thread.start()运行崩了。

让一个线程start/stop/start而已,可这个程序的问题究竟是在哪呢?


public class welcomeView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "welcomeView";
private Bitmap m_bmpWelcomebackage;
private threadWelcome m_thread;

//构造
public welcomeView(Context context) {
super(context);
SurfaceHolder holder = getHolder();
m_thread = new threadWelcome(this, holder);
holder.addCallback(this);
loadPicture();
}

/*
* 函数介绍:界面创建
* 回调函数,来自SurfaceHolder.Callback
* 不会凭空跑,需addCallback后才可
* 输入参数:holder,表面主
* 输出参数:无
* 返回值 :无
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated enter");
if (null != m_thread)
{
Log.v(TAG, "thread start");
m_thread.setSurfaceSupport(true);
m_thread.start(); //最小化后,再次经过此行,崩
}
Log.v(TAG, "surfaceCreated exit");
}

/*
* 函数介绍:界面变更
* 回调函数,来自SurfaceHolder.Callback
* 不会凭空跑,需addCallback后才可
* 输入参数:holder,表面主;format,像素格式;width,宽;height,高
* 输出参数:无
* 返回值 :无
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.v(TAG, "surfaceChanged enter");
Log.v(TAG, "surfaceChanged exit");
}

/*
* 函数介绍:界面摧毁
* 回调函数,来自SurfaceHolder.Callback
* 不会凭空跑,需addCallback后才可
* 输入参数:holder,表面主
* 输出参数:无
* 返回值 :无
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v(TAG, "surfaceDestroyed enter");
if (null != m_thread)
{
Log.v(TAG, "thread stop");
m_thread.setSurfaceSupport(false);
m_thread.stop();
}
Log.v(TAG, "surfaceDestroyed exit");
}

/*
* 函数介绍:屏幕监听
* 重载函数,来自View
* 可以凭空跑了,点击屏幕即可
* 编译器现象:return true行跑完,下一行会落在return super.onTouchEvent(event)
* 输入参数:event,事件类型
* 输出参数:无
* 返回值 :True,已受理;false,未受理
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG, "onTouchEvent enter");
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
Log.v(TAG, "onTouchEvent : action down enter");
Log.v(TAG, "onTouchEvent : action down exit");
return true;
}

Log.v(TAG, "onTouchEvent exit");
return super.onTouchEvent(event);
}

/*
* 线程类介绍:线程
* 以刷帧之用
*/
class threadWelcome extends Thread {
private welcomeView m_wView;
private SurfaceHolder m_sHolder;
private boolean m_bSurface;
/*
* 函数介绍:构造器
* 需要提供包裹类的view和holder,以方便run函数对数据的访问和操作
* 输入参数:v, 视; holder,拥有者
* 输出参数:无
* 返回值 :无
*/
public threadWelcome(welcomeView view, SurfaceHolder sHolder) {
Log.v(TAG, "threadWelcome enter");
m_wView = view;
m_sHolder = sHolder;
Log.v(TAG, "threadWelcome exit");
}

/*
* 函数介绍:线程运行
* 重载函数,来自Thread
* 不会凭空跑,需new此类实例,且start才可
* 输入参数:无
* 输出参数:无
* 返回值 :无
*/
@Override
public void run() {
Log.v(TAG, "run enter");
Canvas cvs;
while (m_bSurface) {
Log.v(TAG, "runing it is...");
cvs = null;
try {
cvs = m_sHolder.lockCanvas(null);
synchronized (m_sHolder) {
m_wView.drawPicture(cvs);
Thread.sleep(100);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
m_sHolder.unlockCanvasAndPost(cvs);
}
}
Log.v(TAG, "run exit");
}

/*
* 函数介绍:设置循环标记位
* 输入参数:flag,true循环 false不循环
* 输出参数:无
* 返回值 :无
*/
public void setSurfaceSupport(boolean bSur) {
m_bSurface = bSur;
}
}

/*
* 函数介绍:从资源里加载图片
* 源文件不能有大写字母
* 输入参数:无
* 输出参数:无
* 返回值 :无
*/
private void loadPicture() {
Log.v(TAG, "loadMusic enter");
Resources res = getResources();
m_bmpWelcomebackage = BitmapFactory.decodeResource(res, R.drawable.welcomebackage);
Log.v(TAG, "loadMusic exit");
}

/*
* 函数介绍:绘画图片
* 图片宽320 hw.lcd.density=160 刚好满屏幕宽度
* 输入参数:canvas,绘画板
* 输出参数:无
* 返回值 :无
*/
private void drawPicture(Canvas canvas) {
Log.v(TAG, "drawPicture enter");
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(m_bmpWelcomebackage, 0, 0, null);
Log.v(TAG, "drawPicture exit");
}
}
...全文
183 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
中才德创 2012-06-10
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

直接再new一个线程就可以了!
[/Quote]呵呵!原来如此。
中才德创 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

java里不需要delete
虚拟机自动进行引用计数,没有引用了,就会进入垃圾回收队列。
[/Quote]thanks!
zy1235678 2012-06-05
  • 打赏
  • 举报
回复
直接再new一个线程就可以了!
ye7813629 2012-06-04
  • 打赏
  • 举报
回复
明显一个线程已经停止了,那这个线程就会被杀掉,要再使用,新建一个线程
RDroid 2012-06-04
  • 打赏
  • 举报
回复
java里不需要delete
虚拟机自动进行引用计数,没有引用了,就会进入垃圾回收队列。
中才德创 2012-06-04
  • 打赏
  • 举报
回复
不会崩了。

m_thread = new threadWelcome(this, holder)经常new,而没有delete,会不会有问题呢?
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated enter");
if (null != m_thread)
{
Log.v(TAG, "thread start");
if (!m_thread.getState().equals(Thread.State.NEW)) {
m_thread = new threadWelcome(this, holder);
}
m_thread.setSurfaceSupport(true);
m_thread.start();
}
Log.v(TAG, "surfaceCreated exit");
}
RDroid 2012-06-04
  • 打赏
  • 举报
回复
扯淡的代码吧.start启动线程来执行run方法和直接执行run方法,区别大了

java里的线程只能start一次,再次start会报异常
中才德创 2012-06-04
  • 打赏
  • 举报
回复
那如下的代码又算啥?
if (m_thread.getState().equals(State.NEW)) {
m_thread.start();
}
else
{
m_thread.run();
}
life02 2012-06-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

每次m_thread.start()前,进行如下判断:
Java code

if (m_thread.getState().equals(State.NEW)) {
m_thread.start();
}
[/Quote]
thread已经start过,要再新建一个线程start
李狗蛋52635 2012-06-04
  • 打赏
  • 举报
回复
ls的程序再加上

else
{
m_thread.run();
}

himi_ 2012-06-04
  • 打赏
  • 举报
回复
每次m_thread.start()前,进行如下判断:

if (m_thread.getState().equals(State.NEW)) {
m_thread.start();
}
  • 打赏
  • 举报
回复
Stop后会Thread就会销毁,LZ需要重新New一个Thread,然后再Start

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧