关于线程再次启动会闪退的问题

时间:2021-10-14 16:22:19
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" 
    android:orientation="vertical"
    android:gravity="center_horizontal">
    <LinearLayout
        android:layout_width="match_parent"
     android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_horizontal">
        <Button
android:id="@+id/go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动"
            />
        <Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"
            />
    </LinearLayout>
    <TextView
        android:id="@+id/jisu_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
        />
</LinearLayout>


package com.example.homework_2;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {


private int jisuqi_1 = 0;//计数器
private mHandler handler;
private mThread thread_1;
private Button go_1,stop_1;
private TextView jisu_1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new mHandler();
thread_1 = new mThread();
jisu_1 = (TextView)findViewById(R.id.jisu_1);
go_1 = (Button)findViewById(R.id.go);
go_1.setOnClickListener(new mCLick());
stop_1 = (Button)findViewById(R.id.stop);
stop_1.setOnClickListener(new mCLick());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

class mCLick implements OnClickListener{//定义按下两个按钮的操作
public void onClick(View v){
if(v == go_1){
thread_1.start();  //再次点下启动时这里就报错
}
if(v == stop_1){
thread_1.flag=true;
}
}
}

class mHandler extends Handler{
public void handleMessage(Message msg){
switch(msg.arg1){
case 1:{
jisuqi_1++;
jisu_1.setText(String.valueOf(jisuqi_1));
break;
}
}
}
}

class mThread extends Thread{
boolean flag = false;
public void run(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
Message msg = new Message();//向handler发送消息
msg.arg1 = 1;
handler.sendMessage(msg);
if(flag){
break;
}
}
}

}
}


问题是,为什么点一次启动,再点一次停止,然后在点起动程序就闪退了~
大概猜的话问题是线程没有结束,又再次启动它可试了许多方法还是不知道怎么结束这个进程
恳请大神解答

7 个解决方案

#1


Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。

#2


thread_1.start() 重复执行会报错,DVM没有那么快回收线程对象。
你可以考虑重新启动一个线程,产生一个新线程。

#3


引用 1 楼 svenwang 的回复:
Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

#4


引用 2 楼 birdsaction 的回复:
thread_1.start() 重复执行会报错,DVM没有那么快回收线程对象。
你可以考虑重新启动一个线程,产生一个新线程。

但如果我每次点开始都NEW一个新线程,结果就是我的计数器像吃了炫迈一样。。。。。。点停止也没有用了,我在想如果每次都NEW一个的话,那该如何停止呢?

#5


引用 3 楼 sha43jie16 的回复:
Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。

#6


引用 5 楼 svenwang 的回复:
Quote: 引用 3 楼 sha43jie16 的回复:

Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。
是这样的,我的程序大意是这样,点启动然后就开始一个线程,然后点停止,这个线程就关闭(或者被挂起也可以),然后再点启动可以开始一个线程(或者激活之前被挂起的线程)

#7


引用 6 楼 sha43jie16 的回复:
Quote: 引用 5 楼 svenwang 的回复:

Quote: 引用 3 楼 sha43jie16 的回复:

Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。
是这样的,我的程序大意是这样,点启动然后就开始一个线程,然后点停止,这个线程就关闭(或者被挂起也可以),然后再点启动可以开始一个线程(或者激活之前被挂起的线程)

要停止线程的话,给线程发一个消息,线程从循环退出并从run函数返回就可以了。
你现在的问题是什么?

#1


Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。

#2


thread_1.start() 重复执行会报错,DVM没有那么快回收线程对象。
你可以考虑重新启动一个线程,产生一个新线程。

#3


引用 1 楼 svenwang 的回复:
Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

#4


引用 2 楼 birdsaction 的回复:
thread_1.start() 重复执行会报错,DVM没有那么快回收线程对象。
你可以考虑重新启动一个线程,产生一个新线程。

但如果我每次点开始都NEW一个新线程,结果就是我的计数器像吃了炫迈一样。。。。。。点停止也没有用了,我在想如果每次都NEW一个的话,那该如何停止呢?

#5


引用 3 楼 sha43jie16 的回复:
Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。

#6


引用 5 楼 svenwang 的回复:
Quote: 引用 3 楼 sha43jie16 的回复:

Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。
是这样的,我的程序大意是这样,点启动然后就开始一个线程,然后点停止,这个线程就关闭(或者被挂起也可以),然后再点启动可以开始一个线程(或者激活之前被挂起的线程)

#7


引用 6 楼 sha43jie16 的回复:
Quote: 引用 5 楼 svenwang 的回复:

Quote: 引用 3 楼 sha43jie16 的回复:

Quote: 引用 1 楼 svenwang 的回复:

Thread对象不需要复用,你重新创建一个就好了。重复执行同一个Thread对象的start方法,内部状态不对了当然报错。
请问可以具体点吗?

你也可以一开始就创建一个线程,点击按钮的时候就给这个线程发消息,线程在自己的循环里处理从UI线程获得的消息。
是这样的,我的程序大意是这样,点启动然后就开始一个线程,然后点停止,这个线程就关闭(或者被挂起也可以),然后再点启动可以开始一个线程(或者激活之前被挂起的线程)

要停止线程的话,给线程发一个消息,线程从循环退出并从run函数返回就可以了。
你现在的问题是什么?