Java 停止线程未使用函数setRunning(false)
我有一个项目,用画布画一条线。我的项目(下载)将创建一个随机数,并使用画布在线连接它们。它工作得很好。但问题是,当我的应用程序运行时,我单击HOME按钮,然后我的应用程序将崩溃,如Java 停止线程未使用函数setRunning(false),java,android,multithreading,canvas,Java,Android,Multithreading,Canvas,我有一个项目,用画布画一条线。我的项目(下载)将创建一个随机数,并使用画布在线连接它们。它工作得很好。但问题是,当我的应用程序运行时,我单击HOME按钮,然后我的应用程序将崩溃,如 FATAL EXCEPTION: Thread-10001 java.lang.NullPointerException at com.example.waveplot.WaveformView.PlotPoints(WaveformView.java:78) at com.example.waveplot.Wave
FATAL EXCEPTION: Thread-10001
java.lang.NullPointerException
at com.example.waveplot.WaveformView.PlotPoints(WaveformView.java:78)
at com.example.waveplot.WaveformPlotThread.run(WaveformPlotThread.java:35)
如何修复它?非常感谢你。
让我解释一下我的申请。我的申请包括三类:
WaveformView.java: class to draw the line in thread with random number.
MainActivity.java: main calss and create the random number and call WaveformView class
WaveformPlotThread: create a thread and manager canvas
这是我的密码
MainActivity.java
private Runnable Timer_Tick = new Runnable() {
public void run() {
numRandom=genNum(0,200)-100;// from -100 to 100
if(dataIndex1<MAX_SAMPLES)
dataY[dataIndex1++] = numRandom;
else
{
dataY[MAX_SAMPLES-1] = numRandom;
for (int i = 0; i < WIDTH/10 - 1; i++)
//Shift data
dataY[i]=dataY[i+1];
}
mWaveform.set_data(dataY);
}
};
这是一个日志文件
D/D(9747): STOOOOOOOOOOOOOOOOOOP
W/SurfaceView(9747): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true realSizeChanged=false redrawNeeded=false left=false top=false
W/System.err(9747): java.lang.IllegalThreadStateException: Thread already started.
W/System.err(9747): at java.lang.Thread.start(Thread.java:1045)
W/System.err(9747): at com.example.waveplot.WaveformView.surfaceCreated(WaveformView.java:41)
W/System.err(9747): at android.view.SurfaceView.updateWindow(SurfaceView.java:609)
W/System.err(9747): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:235)
W/System.err(9747): at android.view.View.dispatchWindowVisibilityChanged(View.java:7625)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1047)
W/System.err(9747): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1346)
W/System.err(9747): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1121)
W/System.err(9747): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4598)
W/System.err(9747): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
W/System.err(9747): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
W/System.err(9747): at android.view.Choreographer.doFrame(Choreographer.java:525)
W/System.err(9747): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
W/System.err(9747): at android.os.Handler.handleCallback(Handler.java:615)
W/System.err(9747): at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(9747): at android.os.Looper.loop(Looper.java:137)
W/System.err(9747): at android.app.ActivityThread.main(ActivityThread.java:4950)
W/System.err(9747): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(9747): at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err(9747): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:997)
W/System.err(9747): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)
W/System.err(9747): at dalvik.system.NativeStart.main(Native Method)
解决方案:根据Veritas的建议,我将创建新线程的函数放入到SurfaceCreated中
@Override
public void surfaceCreated(SurfaceHolder holder){
plot_thread = new WaveformPlotThread(getHolder(), this);
plot_thread.setRunning(true);
plot_thread.start();
}
public WaveformView(Context context, AttributeSet attrs){
super(context, attrs);
getHolder().addCallback(this);
//plot_thread = new WaveformPlotThread(getHolder(), this);
dataY_color.setColor(Color.GREEN);
dataY_color.setStrokeWidth(3);
}
使
\u运行
不稳定,因此读写是原子的。看
四件事
目前,您可以使用surfacecreated方法而不是构造函数来创建新线程。我遇到了相同的问题。我不明白为什么调用
setRunning(false)
时线程不会停止,但我通过在另一个if(canvas!=null)
语句中包装plot\u area.PlotPoints()
绕过了NullPointerException
。因此waveormplotthread
中的run()
方法如下所示:
@Override
public void run(){
Canvas c;
while(_run){
//while(Thread.currentThread() == runner){
c = null;
try{
c = holder.lockCanvas(null);
synchronized (holder) {
if(c!=null) {
plot_area.PlotPoints(c);
}
}
}finally{
if(c!=null){
holder.unlockCanvasAndPost(c);
}
}
}
}
另外,作为旁注,@Override public void onDraw(Canvas Canvas)
不是必需的,并且不建议重写onDraw()
或draw()
。整个方法可以删除。如何在我的应用程序中使用它?它不起作用。请下载我的项目,并尝试使用您的编辑运行它。请注意,当应用程序运行时,按home(主页)按钮返回第一个点时,它将崩溃。然而,在运行应用程序时单击Home按钮仍然会出错。让我们再次检查我的项目。如果您提供了异常StackTracecan,您可以指出WaveformView.java中哪一行号是78,您能帮我展示一个在我的代码中使用它的示例吗?我正在读它。提前感谢我阅读了你的链接,但我不知道如何解决我的问题。你有什么办法解决我的问题吗?相关:谢谢你的评论。正如你所说,我更新了我的代码。然而,我的问题是,当应用程序。运行20秒后,画布将不会绘制。我不知道在我的代码中发生了什么。请在这里查看更多详细信息。请注意,这只发生在真实设备中。在模拟中,它没有problem@user8264我在Nexus7API 5.1.1、模拟Nexus5API 5.1.0和模拟LG OptimusAPI 4.1.1上运行了您的代码。他们都跑得很好。除了Optimus,它没有正确缩放SurfaceView
,但它仍然正确地绘制了绘图。不幸的是,我没有任何其他设备(除了更多的模拟器)可以测试。它可能特定于您的设备。请下载我的代码并在1分钟后运行。你可以看到问题所在。我记录了错误并发布了日志。目前,我通过删除plot_thread.setRunning(false)解决了这个问题;和plot_thread.setRunning(true);在set_数据中function@user8264我又运行了大约十分钟,没有问题。当logcat发生错误时,它是否有任何错误?实际上,我在logcat中找不到任何错误。它只是没有进入绘图区域。绘图点(c);在WaveformPlotThread中。我打印了_run标志,但它仍然是真实值。但是,我刚刚删除了两行plot_thread.setRunning(false);和plot_thread.setRunning(true);那么它工作得很好。我不知道如何检测错误。我在三星Galaxy S2和Note 2中运行它
@Override
public void surfaceCreated(SurfaceHolder holder){
plot_thread = new WaveformPlotThread(getHolder(), this);
plot_thread.setRunning(true);
plot_thread.start();
}
public WaveformView(Context context, AttributeSet attrs){
super(context, attrs);
getHolder().addCallback(this);
//plot_thread = new WaveformPlotThread(getHolder(), this);
dataY_color.setColor(Color.GREEN);
dataY_color.setStrokeWidth(3);
}
public class WaveformPlotThread extends Thread {
private SurfaceHolder holder;
private WaveformView plot_area;
private volatile boolean _run = false;
@Override
public void run(){
Canvas c;
while(_run){
//while(Thread.currentThread() == runner){
c = null;
try{
c = holder.lockCanvas(null);
synchronized (holder) {
if(c!=null) {
plot_area.PlotPoints(c);
}
}
}finally{
if(c!=null){
holder.unlockCanvasAndPost(c);
}
}
}
}