Suleiman Dibirov
Suleiman Dibirov

Reputation: 1023

FATAL EXCEPTION: Thread when using Jsoup

I can't get the title of Google's homepage with Jsoup. I'm getting FATAL EXCEPTION: Thread.

Logcat:

10-19 05:46:44.153: E/AndroidRuntime(597): FATAL EXCEPTION: Thread-75
10-19 05:46:44.153: E/AndroidRuntime(597): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:3939)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:701)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.View.requestLayout(View.java:12555)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.View.requestLayout(View.java:12555)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.View.requestLayout(View.java:12555)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.View.requestLayout(View.java:12555)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.view.View.requestLayout(View.java:12555)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.widget.TextView.checkForRelayout(TextView.java:6716)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.widget.TextView.setText(TextView.java:3256)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.widget.TextView.setText(TextView.java:3110)
10-19 05:46:44.153: E/AndroidRuntime(597):  at android.widget.TextView.setText(TextView.java:3085)
10-19 05:46:44.153: E/AndroidRuntime(597):  at com.example.spravochnik05.MainActivity$1.run(MainActivity.java:34)
10-19 05:46:44.153: E/AndroidRuntime(597):  at java.lang.Thread.run(Thread.java:856)

Code:

public class MainActivity extends Activity {

    private TextView textView;
    public Document doc;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView1);

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    doc = Jsoup.connect("http://google.com").get();
                    textView.setText(doc.title());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

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

New error logcat:

10-19 06:08:28.302: E/AndroidRuntime(846): FATAL EXCEPTION: main
10-19 06:08:28.302: E/AndroidRuntime(846): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.spravochnik05/com.example.spravochnik05.MainActivity}: android.os.NetworkOnMainThreadException
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread.access$600(ActivityThread.java:122)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.os.Looper.loop(Looper.java:137)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread.main(ActivityThread.java:4340)
10-19 06:08:28.302: E/AndroidRuntime(846):  at java.lang.reflect.Method.invokeNative(Native Method)
10-19 06:08:28.302: E/AndroidRuntime(846):  at java.lang.reflect.Method.invoke(Method.java:511)
10-19 06:08:28.302: E/AndroidRuntime(846):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-19 06:08:28.302: E/AndroidRuntime(846):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-19 06:08:28.302: E/AndroidRuntime(846):  at dalvik.system.NativeStart.main(Native Method)
10-19 06:08:28.302: E/AndroidRuntime(846): Caused by: android.os.NetworkOnMainThreadException
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)
10-19 06:08:28.302: E/AndroidRuntime(846):  at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
10-19 06:08:28.302: E/AndroidRuntime(846):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
10-19 06:08:28.302: E/AndroidRuntime(846):  at java.net.InetAddress.getAllByName(InetAddress.java:220)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
10-19 06:08:28.302: E/AndroidRuntime(846):  at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
10-19 06:08:28.302: E/AndroidRuntime(846):  at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:425)
10-19 06:08:28.302: E/AndroidRuntime(846):  at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:410)
10-19 06:08:28.302: E/AndroidRuntime(846):  at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:164)
10-19 06:08:28.302: E/AndroidRuntime(846):  at org.jsoup.helper.HttpConnection.get(HttpConnection.java:153)
10-19 06:08:28.302: E/AndroidRuntime(846):  at com.example.spravochnik05.MainActivity.onCreate(MainActivity.java:26)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.Activity.performCreate(Activity.java:4465)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
10-19 06:08:28.302: E/AndroidRuntime(846):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
10-19 06:08:28.302: E/AndroidRuntime(846):  ... 11 more

How can I fix this?

Upvotes: 0

Views: 3107

Answers (5)

Jitender Dev
Jitender Dev

Reputation: 6925

textView.setText(doc.title());

Remove this line. You cannot update the UI from a thread. Instead use runOnUIThread(), or use a handler for thread.

The best option is to use AsyncTask , which is recommended by Android.

Below is usage of an AsyncTask, which performs background operations in the doInBackground() method and updates the UI in the onPostExecute method.

Here's an example of using an AsyncTask:

In your onCreate method:

new DownloadFilesTask().execute();

And after onCreate ends add this class:

 private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... arg0) {
            doc = Jsoup.connect("http://google.com").get();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            if (doc != null) {
                textView.setText(doc.title());
            }
            else {
                textView.setText("Doc not found");
            }
        }
}

Upvotes: 3

SweetWisher ツ
SweetWisher ツ

Reputation: 7306

Use an AyncTask instead of threads, because this line:

textView.setText(doc.title());

will give you an error as you are getting right now.

Upvotes: 0

Gopal Gopi
Gopal Gopi

Reputation: 11131

You can't change text of TextView in non UI Thread. try to use runOnUIThread(Runnable) method in Activity in non UI Threads for communicating with UI Thread

Upvotes: 0

StephenChen
StephenChen

Reputation: 763

Take the code from your thread, and put it in an AsyncTask thread:

class DownloadFile extends AsyncTask<Void, Void, Void> {
    @Override
    protected String doInBackground(String... arg0) {
                your code
    }

}

Certain actions, such as making HTTP requests, are not allowed to run on the main UI thread.

To execute:

new DownloadFile().execute()

Upvotes: 0

ρяσѕρєя K
ρяσѕρєя K

Reputation: 132982

as in log:

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

means you are trying to update UI elements from non-ui Thread so use AsyncTask or runOnUiThread for update UI elements from non ui Thread.

using runOnUiThread :

 .....
 try {
         doc = Jsoup.connect("http://google.com").get();
         MainActivity.this.runOnUiThread(new Runnable() {

           @Override
            public void run() {
                 textView.setText(doc.title());
             }
          });           
        } catch (IOException e) {
                    // TODO Auto-generated catch block
          e.printStackTrace();
  }

......

Upvotes: 2

Related Questions