程序运行后,surfaceCreated函数进入,m_thread.start()良好。
当程序最小化后,也就是按了手机的第二个按钮,surfaceDestroyed函数进入,m_thread.stop()良好。
再次最大化后,也就是按了手机的第二个按钮,选取该程序,m_thread.start()运行崩了。
让一个线程start/stop/start而已,可这个程序的问题究竟是在哪呢?
- Java code
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"); }}