【问题标题】:Android thread, switch activitiesAndroid线程,切换活动
【发布时间】:2014-06-01 10:44:19
【问题描述】:

我在 Android 上使用 Threads 时遇到了这个问题。 我怎样才能杀死一个线程并开始另一个活动?它可以工作,但是当它切换时,会出现强制关闭错误。 这是正在运行的活动:

public class Game extends Activity implements OnTouchListener{

OurView v;
FileManager fis;
Clock clk;
public float xPos,yPos;
TargetFactory targ = new TargetFactory();
Target target = targ.makeTarget(1);
static int score = 0;
int width = 100;
int height = 200;
static User us  = User.getInstance();



@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    v = new OurView(this);
    v.setOnTouchListener(this);
    fis= new FileManager(this);
    setContentView(v);
    clk = new Clock();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    v.resume();
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    startActivity(new Intent(Game.this,Result.class));
    v.pause();
}

@Override
public synchronized boolean onTouch(View v, MotionEvent me) {

    xPos = me.getX();
    yPos = me.getY();
    target = targ.makeTarget((int) (Math.random()*20));
    switch(me.getAction()){
    case MotionEvent.ACTION_DOWN:
        if(target.targetMove(xPos, yPos, width, height)){
            score ++;
            us.setScore(score);
        }
        else
        {
            score --;
            us.setScore(score);
        }
        break;
    }

    return false;
}


public static int getScore(){
    return score;
}

public class OurView extends SurfaceView implements Runnable{
        Thread t = new Thread(this);
        SurfaceHolder holder;
        User us = User.getInstance();

        boolean ok = false;
        public OurView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            holder = getHolder();
        }

        @Override
        public void run() {
            while(ok == true){
                if(Clock.getSeconds() < 5){             
                if(!holder.getSurface().isValid()){
                    continue;
                }
                Canvas c = holder.lockCanvas();
                Paint p = paint(c);
                holder.unlockCanvasAndPost(c);
                }else{
                    pause();
                    continue;

                }
            }       
        }

        public Paint paint(Canvas c) {
            width = c.getWidth();
            height = c.getHeight();
            c.drawARGB(255, 0, 0, 0);
            Paint p = new Paint();
            p.setColor(Color.WHITE);
            target.drawTarget(c);
            c.drawText(""+score, c.getWidth()-20,20, p);
            return p;
        }

        public void pause(){
            ok = false;
            fis.writeToFile(us);
            t.interrupt();

        } 
        public void checkForPaused() {
            while (ok == false) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {}
            }
    }

        public void resume(){
            target.reset(width, height);
            ok = true;
            t.start();

        }
    }}

这是我试图开始的一个:

public class Result extends Activity {

TextView result;
Button restart;
Button toMenu;
User us = User.getInstance();
FileManager fis;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    fis = new FileManager(this);

    fis.readFromFile();
    setContentView(R.layout.result);


    result = (TextView) findViewById(R.id.score);
    String s = us.getName()+" Result: "+us.getScore();
    result.setText(s);



    restart = (Button) findViewById(R.id.restart);
    restart.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            startActivity(new Intent(Result.this,Game.class));

        }
    });


    toMenu = (Button) findViewById(R.id.retmenu);
    toMenu.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            startActivity(new Intent(Result.this,Menu.class));

        }
    });
}}

抱歉我的英语不好,如果我写了很多代码但我不知道问题出在哪里,也很抱歉。

LogCat:
06-01 10:51:00.464: E/AndroidRuntime(3302): FATAL EXCEPTION: Thread-10

06-01 10:51:00.464: E/AndroidRuntime(3302): java.lang.IllegalMonitorStateException: object not locked by thread before wait()

06-01 10:51:00.464: E/AndroidRuntime(3302):     at java.lang.Object.wait(Native Method)

06-01 10:51:00.464: E/AndroidRuntime(3302):     at java.lang.Object.wait(Object.java:358)

06-01 10:51:00.464: E/AndroidRuntime(3302):     at com.example.firstone.Game$OurView.pause(Game.java:140)

06-01 10:51:00.464: E/AndroidRuntime(3302):     at com.example.firstone.Game$OurView.run(Game.java:118)

06-01 10:51:00.464: E/AndroidRuntime(3302):     at java.lang.Thread.run(Thread.java:1019)

所以我设法通过调用 finish() 方法解决了这个问题。这会停止活动,因此它会停止线程。

【问题讨论】:

  • 能否请您发布 LogCat 输出?这将使我们能够弄清楚是什么导致它崩溃。谢谢

标签: java android multithreading android-activity


【解决方案1】:
public void checkForPaused() {
            while (ok == false) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {}
            }

如果他在暂停中中断,你如何让线程休眠?:

  public void pause(){
            ok = false;
            fis.writeToFile(us);
            t.interrupt();

        } 

它的一个。二:你停止线程,当设置标志为假。中断不需要。

【讨论】:

    【解决方案2】:
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    //empty catch blocks are a terrible habit! Please at least use Log.w!
                }
    

    除此之外,您还滥用了 Object 的线程状态更改方法。当您在对象上调用中断时,它会中断该特定对象实例的监视器中的线程。当您使用链接到特定对象的“同步”块时,线程进入对象的监视器,例如同步(this)。在这种情况下,您假设线程本身被中断,而不是在跟踪其中的线程的东西上调用中断。因此,为什么在使用中断时会收到 IllegalMonitorStateException:线程不在任何对象的监视器中,因此它是非法状态。

    中断线程通常是一种糟糕的处理方式。如果你想结束一个线程,使用一个标志来告诉线程离开它的循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多