【奇葩】SurfaceView绘制画布home后返回黑屏

Jachon 2013-08-29 04:49:16
问题遇到很奇葩,我也不知道什么原因,自己用SurfaceView实现了绘制画布,在线程里面通过lockcanvas获取canvas绘制图形,然后绘制完成后点击home按钮,然后再点击程序图标切回程序后会黑屏大概一段时间(有时候秒进,有时候延时很长),代码奉上
t = new Thread(){
public void run() {
Rect rect = new Rect();
rect.left = 20;
rect.top = 20;
rect.bottom = 100;
rect.right = 300;
loadImage();
SurfaceHolder holder = canvas.getHolder();
while(true){
long start = System.currentTimeMillis();
Canvas g = holder.lockCanvas();
if(g != null){
paintImage(g);
//
holder.unlockCanvasAndPost(g);
}else{
// Thread.yield();//把这句注释去掉就可以解决返回黑屏
}
long end = System.currentTimeMillis() - start;
if(end < 33){
try {
Thread.sleep(33-end);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
};
};
t.start();


其中我在当canvas为空的时候thread.yield一下就可以解决home返回后黑屏,求教是什么原因,我同事用同样的代码,没有yield却没有问题
eclipse版本4.2 ADT版本21.1.0
...全文
360 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
danielinbiti 2013-08-30
  • 打赏
  • 举报
回复
引用 9 楼 codeshine 的回复:
[quote=引用 8 楼 liuh6 的回复:] 在onresume中再画一遍
其实不是绘制问题,是我Canvas g = holder.lockCanvas();获取的canvas一直为空,并且为空的时间很长,所以我比较差异问题出在哪里[/quote] 恩,没注意, SurfaceHolder holder = canvas.getHolder(); 你这canvas是什么参数? holder都是SurfaceView类中this.getHolder();方式获得。
Jachon 2013-08-30
  • 打赏
  • 举报
回复
引用 8 楼 liuh6 的回复:
在onresume中再画一遍
其实不是绘制问题,是我Canvas g = holder.lockCanvas();获取的canvas一直为空,并且为空的时间很长,所以我比较差异问题出在哪里
liuh6 2013-08-30
  • 打赏
  • 举报
回复
在onresume中再画一遍
Jachon 2013-08-30
  • 打赏
  • 举报
回复
引用 5 楼 danielinbiti 的回复:
[quote=引用 4 楼 codeshine 的回复:] [quote=引用 3 楼 danielinbiti 的回复:] Thread.yield();不可用,把线程进入可执行状态后什么时候开始执行看机器运行的线程了
谢谢解答 请问下,把线程进入可执行状态后什么时候开始执行看机器运行的线程了,具体是什么意思?[/quote] 一但yield,就不是你能控制的了,也可能立即执行,也可能很长时间后才有其他进程唤醒你这个thread[/quote] 其实我调用yield是因为我怀疑当前线程导致主线程无法把view显示出来,所以做了下线程yield,结果就解决了,有没有朋友遇到相同问题。
Jachon 2013-08-30
  • 打赏
  • 举报
回复
引用 5 楼 danielinbiti 的回复:
[quote=引用 4 楼 codeshine 的回复:] [quote=引用 3 楼 danielinbiti 的回复:] Thread.yield();不可用,把线程进入可执行状态后什么时候开始执行看机器运行的线程了
谢谢解答 请问下,把线程进入可执行状态后什么时候开始执行看机器运行的线程了,具体是什么意思?[/quote] 一但yield,就不是你能控制的了,也可能立即执行,也可能很长时间后才有其他进程唤醒你这个thread[/quote] 这个明白了,谢谢,现在问题就是不加入yield,每次程序点击home后再从后台切回来会出现黑屏,时间并且不确定多久,昨晚在家里也试了试,已经存在问题,请问您知道这个问题的原因么?
Jachon 2013-08-30
  • 打赏
  • 举报
回复
引用 12 楼 danielinbiti 的回复:
[quote=引用 11 楼 codeshine 的回复:] [quote=引用 10 楼 danielinbiti 的回复:] [quote=引用 9 楼 codeshine 的回复:] [quote=引用 8 楼 liuh6 的回复:] 在onresume中再画一遍
其实不是绘制问题,是我Canvas g = holder.lockCanvas();获取的canvas一直为空,并且为空的时间很长,所以我比较差异问题出在哪里[/quote] 恩,没注意, SurfaceHolder holder = canvas.getHolder(); 你这canvas是什么参数? holder都是SurfaceView类中this.getHolder();方式获得。[/quote] 哈哈我的错,csdn不能重新编辑帖子,在此说明下,canvas(小写的)其实是一个继承surfaceview的类[/quote] 那理解了。 代码上 Canvas g = holder.lockCanvas(); if(g != null){ paintImage(g); // holder.unlockCanvasAndPost(g); //这句要和lockCanvas配套,否则锁住了不解锁 } 另外,你启动线程的地方没看到,看是第一次执行时Canvas没有初始化,导致null,然后又没解锁,后面一直获取null,就进不了paintImage. 其他的根据代码就不好推测了 [/quote] 线程在oncreat里面启动的,是说我的小写canvas没有初始化么?
danielinbiti 2013-08-30
  • 打赏
  • 举报
回复
引用 11 楼 codeshine 的回复:
[quote=引用 10 楼 danielinbiti 的回复:] [quote=引用 9 楼 codeshine 的回复:] [quote=引用 8 楼 liuh6 的回复:] 在onresume中再画一遍
其实不是绘制问题,是我Canvas g = holder.lockCanvas();获取的canvas一直为空,并且为空的时间很长,所以我比较差异问题出在哪里[/quote] 恩,没注意, SurfaceHolder holder = canvas.getHolder(); 你这canvas是什么参数? holder都是SurfaceView类中this.getHolder();方式获得。[/quote] 哈哈我的错,csdn不能重新编辑帖子,在此说明下,canvas(小写的)其实是一个继承surfaceview的类[/quote] 那理解了。 代码上 Canvas g = holder.lockCanvas(); if(g != null){ paintImage(g); // holder.unlockCanvasAndPost(g); //这句要和lockCanvas配套,否则锁住了不解锁 } 另外,你启动线程的地方没看到,看是第一次执行时Canvas没有初始化,导致null,然后又没解锁,后面一直获取null,就进不了paintImage. 其他的根据代码就不好推测了
Jachon 2013-08-30
  • 打赏
  • 举报
回复
引用 10 楼 danielinbiti 的回复:
[quote=引用 9 楼 codeshine 的回复:] [quote=引用 8 楼 liuh6 的回复:] 在onresume中再画一遍
其实不是绘制问题,是我Canvas g = holder.lockCanvas();获取的canvas一直为空,并且为空的时间很长,所以我比较差异问题出在哪里[/quote] 恩,没注意, SurfaceHolder holder = canvas.getHolder(); 你这canvas是什么参数? holder都是SurfaceView类中this.getHolder();方式获得。[/quote] 哈哈我的错,csdn不能重新编辑帖子,在此说明下,canvas(小写的)其实是一个继承surfaceview的类
danielinbiti 2013-08-29
  • 打赏
  • 举报
回复
引用 4 楼 codeshine 的回复:
[quote=引用 3 楼 danielinbiti 的回复:] Thread.yield();不可用,把线程进入可执行状态后什么时候开始执行看机器运行的线程了
谢谢解答 请问下,把线程进入可执行状态后什么时候开始执行看机器运行的线程了,具体是什么意思?[/quote] 一但yield,就不是你能控制的了,也可能立即执行,也可能很长时间后才有其他进程唤醒你这个thread
Jachon 2013-08-29
  • 打赏
  • 举报
回复
引用 3 楼 danielinbiti 的回复:
Thread.yield();不可用,把线程进入可执行状态后什么时候开始执行看机器运行的线程了
谢谢解答 请问下,把线程进入可执行状态后什么时候开始执行看机器运行的线程了,具体是什么意思?
danielinbiti 2013-08-29
  • 打赏
  • 举报
回复
Thread.yield();不可用,把线程进入可执行状态后什么时候开始执行看机器运行的线程了
Jachon 2013-08-29
  • 打赏
  • 举报
回复
有没有兄弟一起来探讨下这个问题..
Jachon 2013-08-29
  • 打赏
  • 举报
回复
并且启动的时候也要好久才能进入绘制的view

80,357

社区成员

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

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