试图在Mainactivity中启动一个线程会导致我的程序崩溃

时间:2014-09-14 12:29:40

标签: android multithreading android-activity crash

我正在尝试制作一个能够持续读取WiFi强度并进行一些处理的应用程序。为了让应用程序更好地运行使用线程,因为我的应用程序需要不断监视wifi信号变化,首先我没有使用线程,因为我触发点击事件开始处理wifi信号(处理代码在while循环中运行)崩溃了。

我的MainActivity看起来像这样:

public class MainActivity extends Activity {
SampleThread s;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);     
    s = new SampleThread(this);
    s.start();

}

public void changeState(View v) {
Switch sw =(Switch) findViewById(R.id.switchx);
    final boolean state = sw.isChecked();
    if (state) {
        s.on();
    } 
    else {
        s.off();
    }
}

线程实现:

public class SampleThread extends Thread {

boolean flag;
Context context;

public SampleThread(Activity c) {
    context =c;
}

@Override
public void run() {
    while(true){
        while(flag){
            work();             
        }
    }
}

void work(){
    //lines of code which process signal strngth
}

void on(){
    flag = true;
}
void off(){
    flag = false;
}

}

如果没有打开开关,我的线程不起作用,并且当它打开时,它会在while循环中启用一个执行实际工作的标志。

我尝试使用带有swing UI的类似代码,它没有任何问题。我对android并不十分精明,我希望能澄清我在这里做错了什么。

我的Logcat看起来像这样:

09-14 17:46:29.902: W/dalvikvm(3632): threadid=11: thread exiting with uncaught exception (group=0x41c9fd40)
09-14 17:46:29.904: E/AndroidRuntime(3632): FATAL EXCEPTION: Thread-6876
09-14 17:46:29.904: E/AndroidRuntime(3632): Process: com.example.tet, PID: 3632
09-14 17:46:29.904: E/AndroidRuntime(3632): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-14 17:46:29.904: E/AndroidRuntime(3632):     at android.os.Handler.<init>(Handler.java:200)
09-14 17:46:29.904: E/AndroidRuntime(3632):     at android.os.Handler.<init>(Handler.java:114)
09-14 17:46:29.904: E/AndroidRuntime(3632):     at com.example.tet.SampleThread.work(SampleThread.java:29)
09-14 17:46:29.904: E/AndroidRuntime(3632):     at com.example.tet.SampleThread.run(SampleThread.java:23)

3 个答案:

答案 0 :(得分:1)

尝试:runOnUiThread(s);而不是s.start();

答案 1 :(得分:1)

从你的onCreate方法

以这种方式运行它
runOnUiThread(new Runnable() {
  public void run() {
   s.start();
  }
});

答案 2 :(得分:1)

为了保持Android应用程序的最高效率,您应该使用Android Serivce或Android Intent Service。 如果你想连续加载Wi_fi,我会建议你使用Android IntentSerivce类。

有链接:         http://developer.android.com/guide/components/services.html

在这里,我将描述它的工作原理,我将展示一些代码:

1)您应该创建新类(例如WiFiCheckerService)并扩展IntentService:

public class WiFiCheckerService extends IntentService
{

   //In this methos serivce receive from other class that it should start operations
   @Override
   protected void onHandleIntent(Intent intent) 
   {
    Thread thread = new Thread(wifiOperations_Runnable);
    thread.start();
   }

  class wifiOperations_Runnable() implements Runnable
  {
     @Override
     public void run()
     {
      while(true)
       {
         //checking wifi state or something...true/false

         broadcastState(state);
       }

     }
  }

   //broadcast wifi state to your MainActivity (where you started service):
   public broadcastState(boolean wifiState)
   {
    Intent intent = new Intent();
    intent.putExtra("WIFI_STATE", wifiState);
    sendBroadcast(intent);
   }

}

2)活动类:在那里你将启动IntentService并从中接收WiFi状态:

public MainActivity extends Activity{

..attributes...


private BroadcastReceiver receiver = new BroadcastReceiver() {


    @Override
    public void onReceive(Context context, Intent intent) {
      Bundle bundle = intent.getExtras();
      if (bundle != null) 
        {
        boolean State = bundle.getBoolean(WIFI_STATE);
        if(State==true
       {
         ...wifi works...
       }
       else
      {
         ..doesnt work...
       }
      }
    }
  };


     ...onCreate(...)
    {
      Intent intent = new Intent(this, WiFiCheckerService.class);
      startSerivce(intent);
    }

 @Override
  protected void onResume()
 {
    super.onResume();
    registerReceiver(receiver);
  }

  @Override
  protected void onPause()
 {
    super.onPause();
    unregisterReceiver(receiver);
  }
}

希望它会有所帮助,不要犹豫提出更多问题!