我是java和andriod的新手,我认为我做错了线程 程序启动没有任何错误。
我已插入一个按钮仅用于测试,它显示没有问题。文本视图甚至不显示“Hello world”默认字符串。
这是代码
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;
}
}
}
答案 0 :(得分:2)
当您启动一个新线程时,UI线程不会等到新线程完成。这就是Threads的目的。
这里:
thread.run();
当您启动新线程以更新stringHandler
时,UI线程会尝试处理下一个命令:
txtView.setText(stringHandler.getString());
当UI线程到达时,stringHandler
尚未更新,因此它为null,因此它将在textview中不显示任何内容。
您应该做的就是在完成后尝试从新线程更新textview。
试试这个:
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());
}
});
}
};
答案 1 :(得分:1)
这部分代码:txtView.setText(stringHandler.getString());
应该在线程完成后放置。
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
我的建议是您在asyncTask
内实施,以便您可以在onPostExecute()
编辑: 这是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());
}
}
并将thread.run()
替换为new StringSet().execute();
答案 2 :(得分:1)
您可以使用处理程序或asyctask来实现此目的。 Asynctask更容易。
http://developer.android.com/reference/android/os/AsyncTask.html
你可以创建自己的线程,但记得在ui线程上更新ui。
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
删除了StringHandler,因为我认为在这种情况下没有必要。
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();
}
}
产生快照