每当我单击 back/home 按钮时,我代码的异步任务部分 closes/stops 应用程序
The asynctask part of my code closes/stops the app whenever I click the back/home button
谁能帮我解决异步任务中的错误?我想我知道为什么它会出错,但我不知道该怎么做才能解决它。非常感谢。
这是我的异步任务代码(只是想将它用于使用 surfaceview 的操纵杆)
public class MySurfaceThread extends AsyncTask<Void, Void, Void> {
SurfaceHolder mSurfaceHolder;
CustomSurfaceView cSurfaceView;
public MySurfaceThread(SurfaceHolder sh, CustomSurfaceView csv) {
mSurfaceHolder = sh;
cSurfaceView = csv;
x = y = 0;
cSurfaceView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
x = event.getX();
y = event.getY();
calculateValues(x, y);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
x = y = 0;
dx = dy = 0;
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
break;
}
return true;
}
private void calculateValues(float xx, float yy) {
dx = xx - zeroX;
dy = yy - zeroY;
angle = (float)Math.atan(Math.abs(dy/dx));
hyp = (float)Math.sqrt((dx * dx) + (dy * dy));
if(hyp > radius) {
if(dx > 0 && dy > 0){ //bottom right
xx = (zeroX + (radius*(float)Math.cos(angle)));
yy = (zeroY + (radius*(float)Math.sin(angle)));
}
else if(dx > 0 && dy < 0){ //top right
xx = (zeroX + (radius*(float)Math.cos(angle)));
yy = (zeroY - (radius*(float)Math.sin(angle)));
}
else if(dx < 0 && dy < 0){ //top left
xx = (zeroX - (radius*(float)Math.cos(angle)));
yy = (zeroY - (radius*(float)Math.sin(angle)));
}
else if(dx < 0 && dy > 0) { //bottom left
xx = (zeroX - (radius*(float)Math.cos(angle)));
yy = (zeroY + (radius*(float)Math.sin(angle)));
}
}
else {
xx = zeroX + dx;
yy = zeroY + dy;
}
x = xx;
y = yy;
}
});
}
@Override
protected Void doInBackground(Void... params) {
Canvas canvas = null;
while (running) {
try {
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
zeroX = canvas.getWidth()/2;
zeroY = canvas.getHeight()/2;
cSurfaceView.onDraw(canvas, x, y, zeroX, zeroY);
}
Thread.sleep(10);
} catch (InterruptedException e) {
} finally {
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
return null;
}
}
我可以使用 runnable 和线程来完成同样的任务吗?如果是这样,如何?谢谢。
编辑
这是 logcat 中的错误消息:
03-09 15:23:52.394 4135-4159/com.example.r.bluetoothsample E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.example.r.bluetoothsample, PID: 4135
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NullPointerException
at com.example.r.bluetoothsample.CustomSurfaceView$MySurfaceThread.doInBackground(CustomSurfaceView.java:182)
at com.example.r.bluetoothsample.CustomSurfaceView$MySurfaceThread.doInBackground(CustomSurfaceView.java:95)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
如果您的表面不可用,lockCanvas()
将 return 为空(我假设当您离开 activity 时它会变为无效)。这意味着您将在 getWidth()
通话中 运行 进入 NullPointerException
。
附带说明一下,我希望您在 activity 的 onPause()
中停止后台循环(可能通过将 running
设置为 false
?)方法——否则,它会一直在后台循环,这是不可取的。
谁能帮我解决异步任务中的错误?我想我知道为什么它会出错,但我不知道该怎么做才能解决它。非常感谢。
这是我的异步任务代码(只是想将它用于使用 surfaceview 的操纵杆)
public class MySurfaceThread extends AsyncTask<Void, Void, Void> {
SurfaceHolder mSurfaceHolder;
CustomSurfaceView cSurfaceView;
public MySurfaceThread(SurfaceHolder sh, CustomSurfaceView csv) {
mSurfaceHolder = sh;
cSurfaceView = csv;
x = y = 0;
cSurfaceView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
x = event.getX();
y = event.getY();
calculateValues(x, y);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
x = y = 0;
dx = dy = 0;
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
break;
}
return true;
}
private void calculateValues(float xx, float yy) {
dx = xx - zeroX;
dy = yy - zeroY;
angle = (float)Math.atan(Math.abs(dy/dx));
hyp = (float)Math.sqrt((dx * dx) + (dy * dy));
if(hyp > radius) {
if(dx > 0 && dy > 0){ //bottom right
xx = (zeroX + (radius*(float)Math.cos(angle)));
yy = (zeroY + (radius*(float)Math.sin(angle)));
}
else if(dx > 0 && dy < 0){ //top right
xx = (zeroX + (radius*(float)Math.cos(angle)));
yy = (zeroY - (radius*(float)Math.sin(angle)));
}
else if(dx < 0 && dy < 0){ //top left
xx = (zeroX - (radius*(float)Math.cos(angle)));
yy = (zeroY - (radius*(float)Math.sin(angle)));
}
else if(dx < 0 && dy > 0) { //bottom left
xx = (zeroX - (radius*(float)Math.cos(angle)));
yy = (zeroY + (radius*(float)Math.sin(angle)));
}
}
else {
xx = zeroX + dx;
yy = zeroY + dy;
}
x = xx;
y = yy;
}
});
}
@Override
protected Void doInBackground(Void... params) {
Canvas canvas = null;
while (running) {
try {
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
zeroX = canvas.getWidth()/2;
zeroY = canvas.getHeight()/2;
cSurfaceView.onDraw(canvas, x, y, zeroX, zeroY);
}
Thread.sleep(10);
} catch (InterruptedException e) {
} finally {
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
return null;
}
}
我可以使用 runnable 和线程来完成同样的任务吗?如果是这样,如何?谢谢。
编辑
这是 logcat 中的错误消息:
03-09 15:23:52.394 4135-4159/com.example.r.bluetoothsample E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.example.r.bluetoothsample, PID: 4135
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NullPointerException
at com.example.r.bluetoothsample.CustomSurfaceView$MySurfaceThread.doInBackground(CustomSurfaceView.java:182)
at com.example.r.bluetoothsample.CustomSurfaceView$MySurfaceThread.doInBackground(CustomSurfaceView.java:95)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
lockCanvas()
将 return 为空(我假设当您离开 activity 时它会变为无效)。这意味着您将在 getWidth()
通话中 运行 进入 NullPointerException
。
附带说明一下,我希望您在 activity 的 onPause()
中停止后台循环(可能通过将 running
设置为 false
?)方法——否则,它会一直在后台循环,这是不可取的。