При нажатии на Android-действие на задний план (нажатие кнопки перехода на приложение или кнопка «домой») приложение немедленно сработает («К сожалению, приложение остановилось»).Сбой активности Android при переключении приложения
Моя деятельность выглядит следующим образом:
public class MyActivity extends Activity {
MyView myView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
}
}
мнение в вопросе использует нить для рисования:
public class MyView extends SurfaceView implements SurfaceHolder.Callback
{
protected Engine engine;
protected SurfaceHolder surfaceHolder;
protected Context context;
private PaintThread thread;
void initView() {
// Initialize our screen holder
SurfaceHolder holder = getHolder();
holder.addCallback(this);
// Get screen size
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
// Initialize engine
engine = new Engine(displayMetrics.widthPixels, displayMetrics.heightPixels);
engine.init(context);
thread = new PaintThread(holder, context, new Handler(), engine);
setFocusable(true);
}
public MyView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
this.context = context;
initView();
}
public MyView(Context context, AttributeSet attrs){
super(context, attrs);
this.context = context;
initView();
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.i("app", "here!");
boolean retry = true;
thread.state = PaintThread.PAUSED;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
if (thread.state == PaintThread.PAUSED){
thread = new PaintThread(getHolder(), context, new Handler(), engine);
thread.start();
} else {
thread.start();
}
}
}
И нить работает так:
public class PaintThread extends Thread {
private SurfaceHolder surfaceHolder;
private Handler handler;
private Context context;
private Engine engine;
public int state = 1;
public final static int RUNNING = 1;
public final static int PAUSED = 2;
public PaintThread(SurfaceHolder surfaceHolder, Context context, Handler handler,
Engine engine) {
this.surfaceHolder = surfaceHolder;
this.handler = handler;
this.context = context;
this.engine = engine;
}
@Override
public void run() {
long previousUpdate = System.nanoTime();
long beforeTime;
long passedTime;
long accumulator = 0;
long dt = 1000/60;
while (state == RUNNING) {
beforeTime = System.nanoTime();
passedTime = TimeUnit.MILLISECONDS.convert(beforeTime - previousUpdate, TimeUnit.NANOSECONDS);
previousUpdate = beforeTime;
accumulator += passedTime;
while (accumulator >= dt) {
engine.update(dt);
accumulator -= dt;
}
Canvas c = null;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
c.drawColor(Color.WHITE);
engine.draw(c);
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
Журнал сообщение в представлении его surfaceDestroyed
метод отображается, когда одна из этих кнопок нажата, но t он в любом случае приложение падает со следующим сообщением:
java.lang.NullPointerException: Попытка вызвать виртуальный метод «недействительный android.graphics.Canvas.drawColor (INT)» на нулевой ссылке на объект
Пострадавшая линия от метода PaintThread
его run
:
c.drawColor(Color.WHITE);
Похоже lockCanvas
это в тот момент, не возвращая Canvas мы можем работать с. Это похоже на предполагаемое поведение, когда холст помещается в фоновом режиме при нажатии одной из этих кнопок.
Но это все происходит только перед тем, как поток приостановлен. Что-то не так с установкой, что это происходит или как это можно предотвратить?
Doh. Я думал, что я делаю что-то неправильно, но это, по-видимому, только то, как работает поиск на холсте. Есть ли какие-либо предположения о том, почему он возвращает нуль в этот момент? – Elias