我刚开始学习动态壁纸,我做了这个小事。
事情是我的应用程序编译出任何问题。
当我在手机中打开它时会在预览中显示壁纸但是当我点击“设置为壁纸”时它会以某种方式崩溃,然后返回前面的屏幕,我的壁纸会变黑,但它不会运行它。
我的猜测是问题是沿着onDestory()的一些地方..
public class Strips extends WallpaperService {
private StripsEngine engine;
@Override
public void onCreate() {
super.onCreate();
engine = new StripsEngine();
engine.resume();
}
@Override
public void onDestroy() {
super.onDestroy();
engine.pause();
}
@Override
public Engine onCreateEngine() {
return engine;
}
class StripsEngine extends Engine implements Runnable {
private Thread t = null;
private SurfaceHolder holder;
private boolean clearToRun = false;
private Paint paint = new Paint();
private Paint paint2 = new Paint();
private int frame;
private float endX,endY;
private int height, width;
private Canvas c;
StripsEngine() {
holder = getSurfaceHolder();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(30);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint2 = paint;
paint2.setColor(Color.BLACK);
paint2.setStrokeWidth(40);
frame = 0;
}
void drawStrips() {
}
public void run() {
// TODO Auto-generated method stub
while (clearToRun) {
if (!holder.getSurface().isValid()) {
continue;
}
height = 800;
width = 480;
endX = (frame) % (width + 10);
endY = (frame / 3) % (height + 10);
if (endX == 0)
paint.setARGB(255,(int)(Math.random()*255), (int)(Math.random()*255),(int)(Math.random()*255));
if (endY ==0)
paint.setARGB(255,(int)(Math.random()*255), (int)(Math.random()*255),(int)(Math.random()*255));
c = holder.lockCanvas();
c.drawLine(endX-30, endY-10, endX , endY,paint);
c.drawLine(endX-30, endY-10, endX , endY,paint);
holder.unlockCanvasAndPost(c);
frame = frame +2;
}
}
public void pause() {
clearToRun = false;
while (true) {
try {
t.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
t = null;
}
public void resume() {
clearToRun = true;
t = new Thread(this);
t.start();
}
}
}
07-06 17:14:43.869:E / Surface(478):错误出列缓冲区(未知错误:-19) 07-06 17:14:43.869:E / Surface(478):dequeueBuffer失败(没有这样的设备) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):异常锁定表面 07-06 17:14:43.869:E / BaseSurfaceHolder(478):java.lang.IllegalArgumentException 07-06 17:14:43.869:E / BaseSurfaceHolder(478):在android.view.Surface.lockCanvasNative(Native Method) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):在android.view.Surface.lockCanvas(Surface.java:288) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):at com.android.internal.view.BaseSurfaceHolder.internalLockCanvas(BaseSurfaceHolder.java:132) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):at com.android.internal.view.BaseSurfaceHolder.lockCanvas(BaseSurfaceHolder.java:112) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):at com.mendel.strips.Strips $ StripsEngine.run(Strips.java:81) 07-06 17:14:43.869:E / BaseSurfaceHolder(478):at java.lang.Thread.run(Thread.java:1096) 07-06 17:14:43.972:W / dalvikvm(478):threadid = 15:线程退出未捕获异常(组= 0x4001b188) 07-06 17:14:43.979:E / AndroidRuntime(478):未捕获的处理程序:由于未捕获的异常而退出的线程-8 07-06 17:14:43.990:E / AndroidRuntime(478):java.lang.NullPointerException 07-06 17:14:43.990:E / AndroidRuntime(478):at com.mendel.strips.Strips $ StripsEngine.run(Strips.java:82) 07-06 17:14:43.990:E / AndroidRuntime(478):at java.lang.Thread.run(Thread.java:1096) 07-06 17:14:43.999:I / dalvikvm(478):threadid = 7:对信号3作出反应 07-06 17:14:43.999:E / dalvikvm(478):无法打开堆栈跟踪文件'/data/anr/traces.txt':权限被拒绝
答案 0 :(得分:1)
这可能是因为您使用holder.lockCanvas()
请求的画布尚未可用,因此它为空,并且您获得NullPointerException。
请参阅lockCanvas()
返回的Canvas可用于绘制到曲面的位图。如果尚未创建表面或无法编辑表面,则返回null。您通常需要实现Callback.surfaceCreated以找出Surface可供使用的时间。
更新
根据您之前调用的isValid()文档 - Does this object hold a valid surface? Returns true if it holds a physical surface, so lockCanvas() will succeed. Otherwise returns false.
此时画布不应为null。但我发现这个,似乎是Android的一个错误:
http://code.google.com/p/android/issues/detail?id=19245
所以你可能不得不尝试Callback.surfaceCreated
方法,或者,如果没有其他方法可行,请尝试超时,如海报(删除帖子),建议,但这是你应该避免的,因为它是不可靠的而且凌乱。
答案 1 :(得分:0)
我得到了答案!
我已经浏览了多维数据集动态壁纸样本并复制了结构,这里是代码:
public class Strips extends WallpaperService {
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
return new StripsEngine();
}
class StripsEngine extends Engine {
private Thread t = null;
;
private boolean clearToRun = false;
private Paint paint = new Paint();
private Paint paint2 = new Paint();
private int frame;
private float endX,endY;
private int height, width;
private Canvas c;
private final Runnable mDrawStrip = new Runnable() {
public void run() {
drawFrame();
}
};
StripsEngine() {
paint.setColor(Color.WHITE);
paint.setStrokeWidth(30);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint2 = paint;
paint2.setColor(Color.BLACK);
paint2.setStrokeWidth(40);
frame = 0;
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawStrip);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
clearToRun = false;
mHandler.removeCallbacks(mDrawStrip);
}
@Override
public void onVisibilityChanged(boolean visible) {
clearToRun = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawStrip);
}
}
public void drawFrame() {
// TODO Auto-generated method stub
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
// draw something
height = 800;
width = 480;
endX = (frame) % (width + 10);
endY = (frame / 3) % (height + 10);
if (endX == 0)
paint.setARGB(255,(int)(Math.random()*255), (int)(Math.random()*255),(int)(Math.random()*255));
if (endY ==0)
paint.setARGB(255,(int)(Math.random()*255), (int)(Math.random()*255),(int)(Math.random()*255));
c.drawLine(endX-30, endY-10, endX , endY,paint);
frame = frame +2;
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mDrawStrip);
if (clearToRun) {
mHandler.postDelayed(mDrawStrip, 1000 / 25);
}
}
}
}