0
我有一個線程問題,我的surfaceView,它很常見,但我沒有找到任何解決方案。SurfaceView從另一個活動返回時崩潰
我使用SurfaceView作爲一個框架佈局的背景:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/blobmusic_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.myapp.Background
android:id="@+id/background_blobmusic"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
...
和我的背景類是tipical surfaceview類,與支架,線程至極會調用我們的onDraw方法等,有些代碼避免問題(的init()被調用構造方法):
public void init() {
ready = false;
holder = getHolder();
holder.addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
while (retry) {
try {
bgdt.setRunning(false);
bgdt.join();
retry = false;
} catch (InterruptedException e) {}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
holder.setFormat(PixelFormat.RGBA_8888);
estrelles = new Estrelles(getResources(),getHeight());
bgdt.setRunning(true);
bgdt.start();
ready = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
});
和我的線程類(bgtd):
public class BGDrawThread extends Thread {
private Background view;
static final long FPS = 60;
private boolean running = false;
public BGDrawThread(Background view) {
this.view = view;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean run) {
running = run;
}
@Override
public void run() {
long ticksPS = 1000/FPS;
long startTime;
long sleepTime;
//fps checker
long contms=0;
long lasttimecheck = System.currentTimeMillis();
int fps=0;
while (running) {
if(contms>1000) {
//souts ??
contms=0;
fps=0;
lasttimecheck = System.currentTimeMillis();
}
else {
fps++;
contms+=System.currentTimeMillis()-lasttimecheck;
lasttimecheck=System.currentTimeMillis();
}
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {}
}
}
}
這工作正常,直到另一個活動前面,然後我們從它回來,那崩潰。
這裏是我的類的onPause /的onResume方法的代碼:
@Override
protected void onResume() {
super.onResume();
Background bmbg = (Background) findViewById(R.id.background_blobmusic);
bmbg.resumethread();
}
@Override
protected void onPause() {
super.onPause();
Background bmbg = (Background) findViewById(R.id.background_blobmusic);
bmbg.stopthread();
}
,並在surfaceview類滑索/恢復線程:
public void stopthread() {
if(!bgdt.isAlive()) return;
boolean retry = true;
while (retry) {
try {
bgdt.setRunning(false);
bgdt.join();
retry = false;
} catch (InterruptedException e) {}
}
}
public void resumethread() {
if(ready && !bgdt.isRunning()) {
bgdt.setRunning(true);
bgdt.start();
}
}
所有幫助都是歡迎的。
編輯:我讓它運行(可能不是一個優雅的解決方案,但我離開代碼在這裏): (看看下面的評論,看看其他的變化)
public void startthread() {
if(!surfacecreated) return;
if(threadrunning) return;
bgdt = new BGDrawThread(this);
bgdt.setRunning(true);
bgdt.start();
threadrunning = true;
}
public void stopthread() {
boolean retry = true;
while (retry) {
try {
bgdt.setRunning(false);
bgdt.join();
threadrunning = false;
retry = false;
} catch (InterruptedException e) {}
}
}
好吧,它不起作用。它甚至在我看到任何主要活動之前崩潰。任何其他想法? – Carles
經過一段時間做了一些測試和一些研究,我發現究竟發生了什麼。 SurfaceChanged僅在調用onStop()時調用,而不是在onPause()之後調用。從這裏我設置了一對控制變量,surfacecreated和threadrunning,並且在我的onStart和onResume方法中調用startthread(),並在我的onPause onResume方法中調用stopthread()。另外startthread()由surfacecreated調用。 我的功能是:(主要職位編輯部分)。 – Carles