This time, I have a problem with calling the wait() method in a new background thread. Tell me, how can I fix the code to remove the error? (On this issue already google, the result is zero, probably I just do not know how to google).

Files and log are attached:

Log:

 08-31 20:39:44.745 29803-29803/******* W/System.err: java.lang.IllegalMonitorStateException: object not locked by thread before wait() at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:407) at com.mathtrainer.superschoolboy.AdditionFragment$18$1.run(AdditionFragment.java:498) at android.app.Activity.runOnUiThread(Activity.java:6039) at com.mathtrainer.superschoolboy.AdditionFragment$18.run(AdditionFragment.java:493) 08-31 20:39:44.746 29803-29803/com.mathtrainer.superschoolboy W/System.err: at java.lang.Thread.run(Thread.java:760) at com.mathtrainer.superschoolboy.AdditionFragment.newforall(AdditionFragment.java:511) at com.mathtrainer.superschoolboy.AdditionFragment.onCreateView(AdditionFragment.java:370) at android.app.Fragment.performCreateView(Fragment.java:2353) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:995) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171) at android.app.BackStackRecord.run(BackStackRecord.java:816) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1580) at android.app.FragmentManagerImpl$1.run(FragmentManager.java:483) at android.os.Handler.handleCallback(Handler.java:754) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:163) at android.app.ActivityThread.main(ActivityThread.java:6228) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794) 

Newforall method:

 private synchronized void newforall(){ //Остальной код (не относится к проблеме) Thread th = new Thread(new Runnable() { @Override public void run() { synchronized (this){ getActivity().runOnUiThread(new Runnable() { @Override public void run() { try{ for(int x = 10; x > 0; x = x - 1) { wait(1000); timerView.setText(Integer.toString(x)); } } catch (Exception e) { Log.e("Timer Thread", "Here is an issue!"); e.printStackTrace(); } } }); } } }); th.run(); } 
  • Why do you need to wait() , and even in UiThread? Most likely, your task can be solved differently. Read about android.os.Handler . You can describe in more detail what you want to achieve and maybe you will be prompted here how to do it better. - woesss pm
  • I want to do something like a timer that will update the interface (display the number of remaining seconds), but use java.util.Timer (because its configuration is too complicated) - Roman Popov
  • Android has a class specifically for this task: CountDownTimer - the documentation has an example of use. - woesss

1 answer 1

Probably because when calling the Object.wait method, the object that is the monitor is incorrectly specified. Try using a different monitor.

 synchronized(this) { try { wait(1000); } catch(InterruptedException ie){} } 
  • Well, this is understandable, but what object (monitor) do you need to use for this? - Roman Popov
  • On which you put the monitor. - Roman C
  • And how to understand what object it is? - Roman Popov
  • an object that is specified in a synchronized statement - Roman C
  • Thanks, but for example, if I wrote in synchonized this? - Roman Popov