我有以下活动。当活动暂停或停止时,我希望活动内的线程终止。我搜索并找到了不适用于我的volatile布尔解决方案。当我将活动置于暂停或停止状态时,继续下载,我不想要它。
public class MyActivity extends Activity {
//some code here
private void foo(){
new Thread (new Runnable (){
@Override
public void run() {
//download something from internet
}
}).start();
}
}
我使用了这种无效的模式:
public class MyActivity extends Activity {
volatile Boolean state = true;
//some code here
private void foo(){
new Thread (new Runnable (){
@Override
public void run() {
while (state) {
//download something from internet
}
}
}).start();
}
@Override
public void onPause(){
super.onPause();
state = false;
}
@Override
public void onStop(){
super.onStop();
state = false;
}
}
答案 0 :(得分:0)
这是一个线程结构的例子,它在击中后退时停止,这是我为我的游戏所做的(并且有效)。一个关键的区别是你在Activity中使用了一个线程,而在我的Activity中我调用了一个View,并在View中运行了一个线程。如果我回击,我会返回我的Activity,并可以通过点击'start'再次调用该线程。因为我的主题行为也是你想要你的方式,即使它发生在View中,我认为你可能会觉得它很有帮助。
我的同步发生的地方是触摸屏值,并确保在线程和调用函数中更新它们。
除非你有办法保存状态(如果你需要),否则线程会完全被删除。
您的线程需要与您希望通过线程控制/共享值的其他函数同步,例如onPause等。
**你需要在你的while循环中有一些同步的测试值,然后可以将状态改为false,否则线程将继续自己,这是线程的点。
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private final GameActivity gameActivity;
private GameThread _thread;
private boolean previouslyRunning = false;
private int width; //Screen width
private int height; //Screen height
private boolean newGame = true;
public GameView(Context context) {
super(context);
getHolder().addCallback(this);
this.gameActivity = (GameActivity) context;
_thread = new GameThread(getHolder(), this);
setFocusable(true);
setFocusableInTouchMode(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w;
height = h;
super.onSizeChanged(w, h, oldw, oldh);
//_thread.initialize();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!previouslyRunning) {
_thread = new GameThread(getHolder(), this);
_thread.initialize();
}
_thread.setRunning(true);
_thread.start();
previouslyRunning = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//TODO - this was an Auto-generated method stub...
//TODO - research what this might be useful for
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Put stuff that needs destructed here.
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// will will try again and again
//TODO: figure it out....
}
}
}
public boolean onTouchEvent(MotionEvent event) {
int numPointers = event.getPointerCount();
int ptrIdx = 0;
int touch = event.getActionMasked();
if (touch == MotionEvent.ACTION_DOWN) {
while (ptrIdx < numPointers) {
int id = event.getPointerId(ptrIdx);
float xp = event.getX(ptrIdx) / width;
if (xp > 0.6) {
_thread.shieldFront = false;
}
if (xp > 0.6 && !attacks) {
attacks = true;
_thread.attackandDefendToggle(true);
} else if (xp > 0.6 && attacks) {
attacks = false;
_thread.attackandDefendToggle(false);
} else if ((xp < 0.4 && xp > 0.2) && !movedRight) {
movedRight = true;
_thread.moveRight(true);
} else if ((xp < 0.4 && xp > 0.2) && movedRight) {
movedRight = false;
_thread.moveRight(false);
} else if (xp < 0.2 && !movedLeft) {
movedLeft = true;
_thread.moveLeft(true);
} else if (xp < 0.2 && movedLeft) {
movedLeft = false;
_thread.moveLeft(false);
}
ptrIdx++;
}
}
if (touch == MotionEvent.ACTION_UP) {
_thread.moveLeft(false);
_thread.moveRight(false);
_thread.attackandDefendToggle(false);
attacks = false;
_thread.shieldFront = true;
}
return true;
}
class GameThread extends Thread {
/****************************
* Public functions *
****************************/
public GameThread(SurfaceHolder surfaceHolder, GameView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
// put sounds here.
soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
//more sounds later
//TODO: create sounds
}
/************************************************
* update() function updates all variables, *
* such as physics, Canvas draw points, score *
* life, etc.. It is called before draw. *
************************************************/
private void update() {
// all the values I want updated with each callback
}
/************************************************
* draw() function creates images on screen, *
* but it performs no logic. *
************************************************/
private void draw(Canvas canvas) {
if (canvas == null) {
return;
}
//Draw stuff on screen
}
public void initialize() {
// Values I want the program to start with;
}
public void setRunning(boolean run) {
_run = run;
}
//Code below actually runs the thread.
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
// Update the game state
update();
// Draw image
draw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}