2013-06-27 19 views
-1

對不起,我發佈了Worng Logcat信息。我更新了這個問題。我想單擊Start來啓動一個線程,然後當單擊enter時,我希望thad繼續並獲取消息並處理線程中的消息,然後將其輸出到主線程並更新文本視圖。我將如何啓動一個線程來等待輸入被按下並獲得處理程序的包? 這裏是我的代碼:如何實現wait();等待notifyAll();從輸入按鈕?

public class MainActivity extends Activity implements OnClickListener { 
Handler mHandler; 
Button enter; 
Button start; 
TextView display; 
String dateString; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    enter = (Button) findViewById(R.id.enter); 
    start = (Button) findViewById(R.id.start); 
    display = (TextView) findViewById(R.id.Display); 
    enter.setOnClickListener(this); 
    start.setOnClickListener(this); 

    mHandler = new Handler() { <=============================This is Line 31 
     public void handleMessage(Message msg) { 
      // TODO Auto-generated method stub 
      super.handleMessage(msg); 
      Bundle bundle = msg.getData(); 
      String string = bundle.getString("outKey"); 
      display.setText(string); 

     } 
    }; 
} 

@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; 
} 

@Override 
public void onClick(View v) { 
    // TODO Auto-generated method stub 
    switch (v.getId()) { 
    case R.id.enter: 
     Message msgin = Message.obtain(); 
     Bundle bundlein = new Bundle(); 
     String in = "It Works!"; 
     bundlein.putString("inKey", in); 
     msgin.setData(bundlein); 
     notifyAll(); 

     break; 
    case R.id.start: 
     new myThread().hello.start(); 
     break; 
    } 
} 

public class myThread extends Thread { 
    Thread hello = new Thread() { 
     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      super.run(); 
      Looper.prepare(); 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      Handler Mhandler = new Handler() { 

       @Override 
       public void handleMessage(Message msg) { 
        // TODO Auto-generated method stub 
        super.handleMessage(msg); 
        Bundle bundle = msg.getData(); 
        dateString = bundle.getString("inKey"); 
       } 

      }; 
      Looper.loop(); 

      Message msg = Message.obtain(); 
      Bundle bundle = new Bundle(); 

      bundle.putString("outKey", dateString); 
      msg.setData(bundle); 
      mHandler.sendMessage(msg); 

     } 

    }; 

} 
} 

這裏是logcat的信息:

06-27 00:00:24.832: E/AndroidRuntime(18513): FATAL EXCEPTION: Thread-1210 
06-27 00:00:24.832: E/AndroidRuntime(18513): java.lang.IllegalMonitorStateException: object not locked by thread before wait() 
06-27 00:00:24.832: E/AndroidRuntime(18513): at java.lang.Object.wait(Native Method) 
06-27 00:00:24.832: E/AndroidRuntime(18513): at java.lang.Object.wait(Object.java:364) 
06-27 00:00:24.832: E/AndroidRuntime(18513): at com 
.example.learninghandlers.MainActivity$myThread$1.run(MainActivity.java:77) 
+0

如果您發佈應用程序的堆棧跟蹤而不是logcat,會更好。 –

+0

它看起來像是在'onCreate()'方法中。用行號,我可以更具體。你有可能會讓你的ID錯誤,或者在使用之前沒有使你的佈局膨脹。 –

+1

哪一行是31? –

回答

0

在此張貼時,您的當前錯誤,

java.lang.IllegalMonitorStateException: object not locked by thread before wait() 

發生,因爲調用線程不當時自己的顯示器,當它試圖等待()。

要擁有監視器,您需要位於您的此類的對象上同步的代碼塊內,或者在您的類的同步方法內。

但是,您對線程的整體使用看起來相當不規則,而且很可能隱藏在這個線程後面的其他問題。

+0

謝謝克里斯我知道這可能更糟糕的編碼,但它的學習目的,將幫助我學習如何理解線程與處理程序和系統中發生了什麼,以及如何解決這些錯誤。 –

+0

我不確定解決這個錯誤會讓你更接近你的目標。老實說,我會從已知的工作示例代碼開始。 –

+0

聽起來像一個計劃,我感謝克里斯的建議。 –

0

如果你看一下堆棧跟蹤你得到的答案是:的的onCreate方法中的對象爲null。

06-26 21:48:55.387: E/AndroidRuntime(15578): Caused by: java.lang.NullPointerException 
06-26 21:48:55.387: E/AndroidRuntime(15578): at com.example.learninghandlers.MainActivity.onCreate(MainActivity.java:31) 

問題在於這些線之間:

setContentView(R.layout.activity_main); 
enter.setOnClickListener(this); 

因爲棧告訴我們,這些使一個計算結果爲空:

enter = (Button) findViewById(R.id.enter); 
start = (Button) findViewById(R.id.start); 
display = (TextView) findViewById(R.id.Display); 

所以問題肯定是在這,東西有null:

R.id.enter 
R.id.start 

你不能通過調試來檢查哪個對象爲空?

+4

這是一條評論不是答案 – Reimeus

+0

@Reimeus它是給定問題的可能答案。你不能調試所有的代碼可以檢查,所以你的答案可以提示。 – Marco

+0

@Marco它不是因爲它沒有提供OP的問題的直接解決方案 –