【问题标题】:How to handle this thread?如何处理这个线程?
【发布时间】:2011-12-26 00:26:24
【问题描述】:

在我的应用程序中,有一个线程在调用活动 A 时运行。现在我要去另一个活动 B 对那个线程什么都不做。 活动 B 上还有另一个线程。 现在在完成活动 B 的活动之后。我回到活动 A。

当时我收到错误消息,活动 A 上的线程已经在运行。 那么,我应该怎么做才能处理这个错误??? 每次我从活动 B 回到活动 A 时,我的应用程序都会崩溃。

谢谢。

在此错误日志中,绘图表面是我的活动 A,如上所述。 错误日志:

11-10 15:08:24.730: ERROR/AndroidRuntime(1145): FATAL EXCEPTION: main
11-10 15:08:24.730: ERROR/AndroidRuntime(1145): java.lang.IllegalThreadStateException: Thread already started.
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at java.lang.Thread.start(Thread.java:1322)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at com.example.drawing.DrawingSurface.surfaceCreated(DrawingSurface.java:113)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.SurfaceView.updateWindow(SurfaceView.java:532)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.View.dispatchWindowVisibilityChanged(View.java:3891)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:719)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewRoot.performTraversals(ViewRoot.java:744)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.os.Looper.loop(Looper.java:123)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at android.app.ActivityThread.main(ActivityThread.java:4627)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at java.lang.reflect.Method.invokeNative(Native Method)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at java.lang.reflect.Method.invoke(Method.java:521)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-10 15:08:24.730: ERROR/AndroidRuntime(1145):     at dalvik.system.NativeStart.main(Native Method)

出现错误的 DrawingSurface 类:

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
private Boolean _run;
protected DrawThread thread;
public Canvas canvas = null;
private CommandManager commandManager;
//private Bitmap myBitmap;
private Bitmap mBitmap;

public DrawingSurface(Context context, AttributeSet attrs) {
    super(context, attrs);

    getHolder().addCallback(this);

    commandManager = new CommandManager();
    thread = new DrawThread(getHolder());
}

class DrawThread extends Thread{
    private SurfaceHolder mSurfaceHolder;

    public DrawThread(SurfaceHolder surfaceHolder){
        mSurfaceHolder = surfaceHolder;

    }

    public void setRunning(boolean run) {
        _run = run;
    }

    @Override
    public void run() {
        //Canvas canvas = null;
        while (_run){

            try{
                canvas = mSurfaceHolder.lockCanvas(null);
                if(mBitmap == null){
                    mBitmap =  Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
                }

                final Canvas c = new Canvas (mBitmap);
                //canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                c.drawColor(0, PorterDuff.Mode.CLEAR);
                canvas.drawColor(Color.WHITE); 
//             Bitmap kangoo =   BitmapFactory.decodeResource(getResources(),R.drawable.icon);

                if(!(DrawingActivity.imagePath==null)){
                    c.drawBitmap(DrawingActivity.mBitmap, 0, 0, null);
                }
                commandManager.executeAll(c);
                canvas.drawBitmap (mBitmap, 0,  0,null);
            } finally {

                mSurfaceHolder.unlockCanvasAndPost(canvas);
            }
        }

    }
}


public void addDrawingPath (DrawingPath drawingPath){
    commandManager.addCommand(drawingPath);
}

public boolean hasMoreRedo(){
    return commandManager.hasMoreRedo();
}

public void redo(){
    commandManager.redo();
}

public void undo(){
    commandManager.undo();
}

public boolean hasMoreUndo(){
    return commandManager.hasMoreRedo();
}

public Bitmap getBitmap(){
    return mBitmap;
}


public void surfaceChanged(SurfaceHolder holder, int format, int width,  int height) {
    // TODO Auto-generated method stub
    mBitmap =  Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);;
}

public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
        thread.setRunning(true);
        thread.start(); // error at this line
        if(!thread.isAlive())            
             thread.start();  
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    boolean retry = true;
    thread.setRunning(false);
    while (retry) {
        try {
            thread.join();
            retry = false;
        } catch (InterruptedException e) {
            // we will try it again and again...
        }
    }
}

}

【问题讨论】:

  • 发布一些代码和错误日志。
  • 你在哪些活动方法中启动线程运行?
  • 请贴出线程代码,你是如何实现线程的。
  • 在我的应用程序中,我正在运行线程以在画布上绘画和绘图。如果我从那里调用另一个活动然后回来,那时我会出错。我只是要上传错误日志。
  • 只需阅读错误日志并告诉我。我会放那个代码。

标签: android multithreading android-layout android-emulator android-widget


【解决方案1】:

如果您使用AsyncTask,而不是使用ThreadRunnable,它们会在您离开活动后自动关闭。

或者,如果您只想使用Thread,则必须使用t.interrupt() 停止任何正在运行的Thread t,然后再离开活动。

所以,我想将t.interrupt() 放入活动的onPause() 方法中以停止Thread

编辑:这一行是多余的

if(!thread.isAlive())            
             thread.start();  

我不明白你想用这个做什么,

thread.setRunning(true);

这可能会造成一些问题,删除它并重试

即试试这个

public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
        thread.start(); // error at this line 
}

【讨论】:

  • 嗯..让我仔细看看
  • 我已经编辑了我的答案,尝试在包含此视图的活动的 onPause() 中使用 thread.interrupt(),检查它是否解决了问题
  • 好的。我来检查一下。如果您更新答案,请告诉我。
  • 您可能是对的,但我正在使用该代码在画布上绘图。这就是我使用它的原因。现在如何解决这个问题?如果我评论说它不起作用。
  • 我被难住了,试试这个,当用户离开时完成你的活动,用 FLAG_CLEAR_TOP 开始活动,看看它是否有效,我建议你在这个上开始赏金
【解决方案2】:

这不起作用(大部分时间 -> 竞争条件):

   thread.start(); // error at this line
   if(!thread.isAlive()) thread.start();

不要那样做。一个线程只能启动一次,并且绝对没有理由重新尝试启动它。

thread.start(); 确实是您启动线程所需的全部内容。

编辑:

while (retry) {
  thread.join();
  retry = false;
}

没有任何意义。只需join() 并可能将中断转发给您的thread

【讨论】:

  • 好的。但即使我评论那两行,我也得到了同样的错误。现在我该怎么办?
  • 正如我所说:您不能启动线程超过一次。但是,在您的代码中,您只在构造函数中创建 one 线程对象,可能会要求多次 start(),即每次 surfaceCreated() 被执行。您可能需要在 surfaceCreated() 中创建一个新线程。
  • 现在的错误是什么? - 向我们展示您编辑的代码和新的 logcat。
  • 同样的错误。如果我回来了,应用程序就不能在画布上绘制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
相关资源
最近更新 更多