Reputation: 97
I am new to java and andriod and i think that i did something wrong with thread Program starts without any errors.
I have inserted one button just for test and it shows without problem. Text view doesnt even displays "Hello world" default string.
Here is the code
package com.example.studentservis;
import android.R.string;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.w3c.dom.Text;
public class MainActivity extends Activity {
StringHandler stringHandler = new StringHandler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thread.run();
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
}
};
public String webRequest() throws Exception{
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
public class StringHandler
{
public String str = "test";
public void setString(String s)
{
str = s;
}
public String getString()
{
return str;
}
}
}
Upvotes: 1
Views: 1300
Reputation: 133580
You can use a handler or a asyctask for this purpose. Asynctask is easier.
http://developer.android.com/reference/android/os/AsyncTask.html
You can create your own thread but remember to update ui on the ui thread.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="166dp"
android:text="Loading..." />
</RelativeLayout>
MainActivity.java
Removed StringHandler cause i felt it was unnecessary in this context.
public class MainActivity extends Activity {
TextView txtView ;
String s;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtView = (TextView)this.findViewById(R.id.textView1); // initialize textview
//txtView.setText(stringHandler.getString());
new Thread(new Runnable() { // thread
@Override
public void run(){
try {
s = webRequest(); // get string
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() //run on ui threa
{
public void run()
{
txtView.setText(s); // update ui on the ui thread.
}
});
}
}).start();
}
public String webRequest() throws Exception{ // web request
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
}
Resulting snap shot
Upvotes: 1
Reputation: 3366
When you start a new Thread, the UI thread won't wait until the new thread is complete. That is the purpose of the Threads.
Here :
thread.run();
When you a start the new thread to update the stringHandler
, the UI thread tries to process the next command which is :
txtView.setText(stringHandler.getString());
When the UI thread gets to this, the stringHandler
hasn't updated yet, so It's null and thus it will show nothing in the textview.
All you should do is to try to update the textview from the new Thread when it's finished.
Try this:
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
});
}
};
Upvotes: 2
Reputation: 1632
This part of your code : txtView.setText(stringHandler.getString());
should be put after the thread finished.
thread.run(); <------ Start running thread in background
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
// the textView was set without knowing whether the Thread is finished or not.
// thus, textView is shown as empty, because stringHandler.getString() still has empty string
My suggestion is that you implement it inside an asyncTask
, so that you can set the text within onPostExecute()
Good luck ^^
EDIT : here's some example AsyncTask
private class StringSet extends AsyncTask <Void,Void,Void> {
@Override
protected void doInBackground(Void... params) {
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
stringHandler.setString(e.getMessage());
}
}
@Override
protected void onPostExecute(Void... results) {
txtView.setText(stringHandler.getString());
}
}
And replace your thread.run()
with new StringSet().execute();
Upvotes: 1