2014-02-04 21 views
0

Я сделал следующий код, чтобы показать простой твиттер, но при этом возникает ошибка. Может быть, потому, что я делаю фрагменты, но я не уверен. Я последовал за учебником о том, как создать твиттер-канал, поэтому он должен был работать, но я не знаю. Можете ли вы, ребята, найти проблему?Ошибка NetworkOnMainThreadException?

package info.android.icecreamparties; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.StatusLine; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 
import android.app.Fragment; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

public class HomeFragment extends Fragment { 

TextView tweetTextView; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) 

{ 


    View rootView = inflater.inflate(R.layout.fragment_home, container, false); 

    TextView about = (TextView)rootView.findViewById(R.id.homepageintro); 
    Typeface bb = Typeface.createFromAsset(getActivity().getAssets(), "BebasNeue.otf"); 
    about.setTypeface(bb); 

    String twitterTimeline = getTwitterTimeline(); 
    try { 
    String tweets = ""; 
    JSONArray jsonArray = new JSONArray(twitterTimeline); 
    for (int i = 0; i < jsonArray.length(); i++) { 
     JSONObject jsonObject = jsonArray.getJSONObject(i); 
     int j = i + 1; 
     tweets += "Tweet #" + j + " \n"; 
     tweets += "Date:" + jsonObject.getString("created_at") + "\n"; 
     tweets += "Post:" + jsonObject.getString("text") + "\n\n"; 
    } 
    tweetTextView = (TextView)rootView.findViewById(R.id.twitterfeed); 
    tweetTextView.setText(tweets); 
    } catch (JSONException e) { 
    e.printStackTrace(); 
    } 
    return rootView; 
    } 

    public String getTwitterTimeline() { 
    StringBuilder builder = new StringBuilder(); 
    HttpClient client = new DefaultHttpClient(); 
    HttpGet httpGet = new HttpGet(
     "http://api.twitter.com/1/statuses/user_timeline/BBCNews.json?count=10&include_rts=1&callback=?"); 
    try { 
    HttpResponse response = client.execute(httpGet); 
    StatusLine statusLine = response.getStatusLine(); 
    int statusCode = statusLine.getStatusCode(); 
    if (statusCode == 200) { 
     HttpEntity entity = response.getEntity(); 
     InputStream content = entity.getContent(); 
     BufferedReader reader = new BufferedReader(
     new InputStreamReader(content)); 
     String line; 
     while ((line = reader.readLine()) != null) { 
     builder.append(line); 
     } 
    } else { 
     // Display couldn't obtain the data from twitter 
    } 
    } catch (ClientProtocolException e) { 
    e.printStackTrace(); 
    } catch (IOException e) { 
    e.printStackTrace(); 
    } 
    return builder.toString(); 
    } 

} 
+0

[См этот пример AsyncTask] (http://stackoverflow.com/questions/18898039/using-asynctask/18898105#18898105) положить сетевой код в 'doInBackground()' и 'обновление UI' в другие методы. – codeMagic

+1

Grrrrrrrr. Поиск вперёд! Как вы думаете, вы первый человек, который это видит? – Simon

ответ

1

Вам нужно позвонить getTwitterTimeline на нитку без пользовательского интерфейса. Позвоните по номеру AsyncTask или Loader. Что-то вроде (слепой код в Notepad ++):

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    final View rootView = inflater.inflate(R.layout.fragment_home, container, false); 
    TextView about = (TextView)rootView.findViewById(R.id.homepageintro); 
    Typeface bb = Typeface.createFromAsset(getActivity().getAssets(), "BebasNeue.otf"); 
    about.setTypeface(bb); 
    new AsyncTask<Void, Void, String>() { 
     public String doInBackground(Void ... params) { 
      return getTwitterTimeline(); 
     } 
     protected void onPostExecute(String twitterTimeline) { 
      try { 
       String tweets = ""; 
       JSONArray jsonArray = new JSONArray(twitterTimeline); 
       for (int i = 0; i < jsonArray.length(); i++) { 
        JSONObject jsonObject = jsonArray.getJSONObject(i); 
        int j = i + 1; 
        tweets += "Tweet #" + j + " \n"; 
        tweets += "Date:" + jsonObject.getString("created_at") + "\n"; 
        tweets += "Post:" + jsonObject.getString("text") + "\n\n"; 
       } 
       TextView tweetTextView = (TextView)rootView.findViewById(R.id.twitterfeed); 
       tweetTextView.setText(tweets); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    }.execute(); 
    return rootView; 
} 
+0

Да, загрузчик также является хорошим выбором, но вам нужно использовать вспомогательный загрузчик, чтобы вернуться к API 11. См. Https://developer.android.com/reference/android/content/Loader.html и https://developer.android.com/reference/android/support/v4/content/Loader.html –

+0

Я пробовал это, но, похоже, есть ошибки в защищенной пустоте onPostExecute (String) и public String doInBackground (Void .. .). Ошибка объявления переменных – user3198241

+0

Как сказано, слепое кодирование с Notepat ++ ... исправлено ошибки, вы можете сделать снимок. – gunar

0

Вам нужно запустить getTwitterTimeline в другом потоке. Я предлагаю создать AsyncTask в onCreateView(). Исключением, которое вы получаете, является то, что пользовательский интерфейс не может быть нарисован, пока вы ожидаете возвращения твиттера с ответом. Таким образом, проблема «Сеть по главной теме».

Смотрите здесь:

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

0

Используйте AsyncTask класс, чтобы получить данные щебет, вы не можете использовать UI поток для получения данных из сети.

0

Вы размещаете сетевую связь по основной теме. Вам не разрешено это делать. Вы можете использовать AsyncTask

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

Только для тестирования вы можете добавить следующее в основной деятельности, но это считают плохой практикой.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
StrictMode.setThreadPolicy(policy); 
Смежные вопросы