2013-06-03 4 views
1

Я новичок в 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; 
      } 
     } 



    } 

ответ

1

Вы можете использовать обработчик или asyctask для этой цели. Asynctask проще.

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

Вы можете создать свой собственный поток, но не забудьте обновить пользовательский интерфейс на потоке пользовательского интерфейса.

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(); 
} 
} 

Результирующая ФОТОГРАФИЯ

enter image description here

+0

Он не обновляет поток пользовательского интерфейса из другого потока. Он обновил пользовательский интерфейс из потока пользовательского интерфейса. Это не проблема. Проблема в том, что когда он хочет обновить пользовательский интерфейс, новый Thread еще не закончен и не имеет готовых данных –

+1

@MiroMarkarian согласился, я обновил свой ответ, если у вас есть downvoted, вы можете удалить то же самое сейчас – Raghunandan

+0

Хорошо. Но в любом случае это то же самое, что и мой ответ :) –

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()

удачи ^^

EDIT: Вот пример 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();

+0

я не знаю, как реализовать свой код. Im получает ошибки на 'protected void doInBackground (Void ... params)' и 'protected void onPostExecute (Void ... results)' – imot01

+0

Вы отредактировали код на eclipse IDE, правильно ?, тогда вам нужно только написать 'private класс StringSet расширяет AsyncTask {} 'и позволяет Eclipse обрабатывать реализацию метода для вас Попробуйте нажать Alt + Shift + S внутри класса' asyncTask' и выберите «методы переопределения/реализации», выберите 'doInBackground' и' onPostExecute' вы должны это сделать ^^ – reidzeibel

2

Когда вы начинаете новую тему, поток пользовательского интерфейса не будет ждать завершения нового потока. Это цель Threads.

Здесь:

thread.run(); 

Когда Вы начинаете новый поток для обновления stringHandler, поток UI пытается обработать следующую команду, которая:

txtView.setText(stringHandler.getString()); 

Когда поток пользовательского интерфейса получает это, stringHandler еще не обновлено, так что оно равно null, и поэтому оно ничего не покажет в текстовом виде.

Все, что вам нужно сделать, это попытаться обновить текстовое представление из новой темы, когда она будет готова.

Попробуйте это:

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()); 
      } 
     }); 
    } 
}; 
+0

Мог ли я просто добавить 'thread.join();' after' stringHandler.setString (webRequest()); '? Присоединяйся к потоку, верно? – imot01

+0

Присоединение приостанавливает текущую цепочку и ожидает завершения другой нити. это не просто хорошая идея. потому что это делает ваш пользовательский интерфейс невосприимчивым (= приложение зависает, не будет реагировать на взаимодействие с пользователем). Я бы не рекомендовал это –

+0

Если вы действительно хотите использовать его, который должен быть после 'thread.start()' не после 'stringHandler.setString (webRequest());' –

Смежные вопросы