Reputation: 183
I have the following code, in which I try to connect to google.com and parse the text on that site:
package com.example.parsetest;
import java.io.IOException;
import org.jsoup.*;
import org.jsoup.nodes.Document;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@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;
}
Thread downloadThread = new Thread() {
public void run() {
Document doc;
try {
doc = Jsoup.connect("http://google.com/").get();
String title = doc.title();
TextView console = (TextView) findViewById(R.id.textview1);
console.setText(title);
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
My issue is that I'm unsure as to whether I've created my new thread properly, and where I'm supposed to call downloadThread.start()
from - am I supposed to create a new class? Or do I call it from my onCreate method?
Upvotes: 0
Views: 2030
Reputation: 133560
Yes you need to call downloadThread.start()
. You cannot update ui from a background thread. Use runOnUiThread
public class MainActivity extends Activity {
TextView console;
String title;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
console = (TextView) findViewById(R.id.textView1);
new Thread() {
public void run() {
Document doc;
try {
doc = Jsoup.connect("http://google.com/").get();
title = doc.title();
runOnUiThread( new Runnable()
{
public void run()
{
console.setText(title); // set text on the ui thread
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
As other have suggested using asynctask is easier.
http://developer.android.com/reference/android/os/AsyncTask.html
Using AsyncTask
public class MainActivity extends Activity {
TextView console;
String title;
ProgressDialog pd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pd = new ProgressDialog(this);
pd.setMessage("Jsoup parsing...");
console = (TextView) findViewById(R.id.textView1);
new TheTask().execute();
}
class TheTask extends AsyncTask<Void,String,String>
{
@Override
protected String doInBackground(Void... arg0) {
// TODO Auto-generated method stub
Document doc;
try {
doc = Jsoup.connect("http://google.com/").get();
title = doc.title();
}
catch(Exception e)
{
e.printStackTrace();
}
return title;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
console.setText(title);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd.show();
}
}
}
Upvotes: 2
Reputation: 132982
I'm unsure as to whether I've created my new thread properly
Yes you have created Thread in right way but inside run method you are updating TextView text which is not valid because only main thread updated ui elements instead of any other thread. you should use runOnUiThread
for updating TextView :
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
TextView console = (TextView) findViewById(R.id.textview1);
console.setText(title);
}
});
suggested way is use AsyncTask
where I'm supposed to call downloadThread.start() from
you should call downloadThread.start()
in onCreate of Activity after setContentView
Upvotes: 0
Reputation: 11396
check out android AsyncTask usage example
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
the download should be taken place at doInBackground
Upvotes: 0