pfpflwho / java-ide-droid

Automatically exported from code.google.com/p/java-ide-droid
0 stars 0 forks source link

Code review request #1

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In MainActivity, there is the method fnRunBeanshellScript2 which should replace 
fnRunBeanshellScript and add a ProgressDialog. But every time this method is 
called, the app crashes.

What is wrong with code? I can't see the problem.

Tom

Original issue reported on code.google.com by tom.ar...@gmail.com on 4 May 2011 at 7:23

GoogleCodeExporter commented 9 years ago
I used logcat to find this exception being thrown for the crash:

E/AndroidRuntime( 9301): FATAL EXCEPTION: Thread-10
E/AndroidRuntime( 9301): java.lang.RuntimeException: Can't create handler 
inside thread that has not called Looper.prepare()
E/AndroidRuntime( 9301):    at android.os.Handler.<init>(Handler.java:121)
E/AndroidRuntime( 9301):    at android.widget.Toast.<init>(Toast.java:68)
E/AndroidRuntime( 9301):    at android.widget.Toast.makeText(Toast.java:231)
E/AndroidRuntime( 9301):    at 
com.t_arn.JavaIDEdroid.MainActivity.fnToast(MainActivity.java:341)
E/AndroidRuntime( 9301):    at 
com.t_arn.JavaIDEdroid.MainActivity.fnError(MainActivity.java:250)
E/AndroidRuntime( 9301):    at 
com.t_arn.JavaIDEdroid.MainActivity.access$0(MainActivity.java:247)
E/AndroidRuntime( 9301):    at 
com.t_arn.JavaIDEdroid.MainActivity$1.run(MainActivity.java:331)
E/AndroidRuntime( 9301):    at java.lang.Thread.run(Thread.java:1096)
W/ActivityManager( 1090):   Force finishing activity 
com.t_arn.JavaIDEdroid/.MainActivity

I added the Looper.prepare() function at the beginning of your run method, and 
then moved the dismissDialog(DIALOG_PROGRESS) to after the try-catch block, 
like this:

      public void run()
      {
        Looper.prepare();
        final bsh.Interpreter i;
        try
        {
          i = new bsh.Interpreter();
          i.set("mainActivity", MainActivity.this);
          ide.fnRunBeanshellScript(i, script);
        }
        catch (Throwable t)
        {
          fnError("fnRunBeanshellScript", t);
        }
        dismissDialog(DIALOG_PROGRESS);
      }//run

but then I saw this error:

E/AndroidRuntime( 9434): FATAL EXCEPTION: Thread-15
E/AndroidRuntime( 9434): android.view.ViewRoot$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 9434):    at 
android.view.ViewRoot.checkThread(ViewRoot.java:2802)
E/AndroidRuntime( 9434):    at 
android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
E/AndroidRuntime( 9434):    at 
android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
E/AndroidRuntime( 9434):    at 
android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
E/AndroidRuntime( 9434):    at android.view.View.invalidate(View.java:5139)
E/AndroidRuntime( 9434):    at 
android.widget.TextView.updateAfterEdit(TextView.java:4734)
E/AndroidRuntime( 9434):    at 
android.widget.TextView.handleTextChanged(TextView.java:6158)
E/AndroidRuntime( 9434):    at 
android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:6316)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:8
89)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:259)
E/AndroidRuntime( 9434):    at 
android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:28)
E/AndroidRuntime( 9434):    at android.widget.TextView.append(TextView.java:2240)
E/AndroidRuntime( 9434):    at android.widget.TextView.append(TextView.java:2227)
E/AndroidRuntime( 9434):    at 
com.t_arn.lib.ui.GenericAndroidTextArea.append(GenericAndroidTextArea.java:20)
E/AndroidRuntime( 9434):    at 
com.t_arn.lib.io.GenericTextAreaOutputStream.flush(GenericTextAreaOutputStream.j
ava:67)
E/AndroidRuntime( 9434):    at 
com.t_arn.lib.io.GenericTextAreaOutputStream.write(GenericTextAreaOutputStream.j
ava:75)
E/AndroidRuntime( 9434):    at java.io.OutputStream.write(OutputStream.java:122)
E/AndroidRuntime( 9434):    at java.io.PrintStream.write(PrintStream.java:688)
E/AndroidRuntime( 9434):    at 
java.io.FilterOutputStream.write(FilterOutputStream.java:106)
E/AndroidRuntime( 9434):    at java.io.PrintStream.print(PrintStream.java:497)
E/AndroidRuntime( 9434):    at java.io.PrintStream.newline(PrintStream.java:386)
E/AndroidRuntime( 9434):    at java.io.PrintStream.println(PrintStream.java:630)
E/AndroidRuntime( 9434):    at 
java.lang.Throwable.printStackTrace(Throwable.java:279)
E/AndroidRuntime( 9434):    at 
java.lang.Throwable.printStackTrace(Throwable.java:220)
E/AndroidRuntime( 9434):    at 
com.t_arn.JavaIDEdroid.MainActivity.fnError(MainActivity.java:251)
E/AndroidRuntime( 9434):    at 
com.t_arn.JavaIDEdroid.MainActivity.access$0(MainActivity.java:247)
E/AndroidRuntime( 9434):    at 
com.t_arn.JavaIDEdroid.MainActivity$1.run(MainActivity.java:331)
E/AndroidRuntime( 9434):    at java.lang.Thread.run(Thread.java:1096)
W/ActivityManager( 1090):   Force finishing activity 
com.t_arn.JavaIDEdroid/.MainActivity

This seems to be because you have redefined System.out to push the output to a 
TextView, and you're trying to update that TextView from the thread, and not 
from the main program. You are only allowed to touch the Views from the main 
thread, all other threads are forbidden and throw this error.

If you still want the error message from any fnError call to go to the 
TextView, I would recommend using AsyncTask for this operation, it has methods 
that can touch the views and still lets you run a process in the background. 

http://developer.android.com/reference/android/os/AsyncTask.html

Alternatively for some of these app-specific errors, you can use Log.d() to 
push your output to the internal log files.

Original comment by mark.goadrich on 19 May 2011 at 3:39

GoogleCodeExporter commented 9 years ago
Marc,

Many thanks for your help!
I'll look into AsyncTask and see if it solves the problem.

Tom

Original comment by tom.ar...@gmail.com on 20 May 2011 at 10:30

GoogleCodeExporter commented 9 years ago
OK, after a lot of trial and error, I got a little demo app working now with 
AsyncTask.
Now, I'll integrate that into JavaIDEdroid.

Thanks again
Tom

Original comment by tom.ar...@gmail.com on 31 May 2011 at 7:30

GoogleCodeExporter commented 9 years ago
The code is integrated and working in version 0.7.0

Tom

Original comment by tom.ar...@gmail.com on 10 Jun 2011 at 5:54

GoogleCodeExporter commented 9 years ago

Original comment by tom.ar...@gmail.com on 17 Aug 2011 at 5:22