2011-09-13 16 views
8

Zdaję sobie sprawę, że ten błąd występuje, gdy próbujesz wykonać jakieś żądanie sieciowe w wątku interfejsu użytkownika, ale jak widać w poniższym kodzie, w rzeczywistości nazywam Http Get in AsyncTask :android.os.NetworkOnMainThreadException w AsyncTask

public class LeftPaneFragment extends Fragment { 

    private ImageView _profileImage; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(wj.tweetTab.R.layout.left_pane, container); 

     _profileImage = (ImageView) view.findViewById(R.id.profileImage); 

     setUpProfileInfo(view); 

     return view; 
    } 

    private void setUpProfileInfo(View view) {   
     new SetUpUserInfo().doInBackground(); 
    } 

    private class SetUpUserInfo extends AsyncTask<Void, Void, Drawable> { 

     @Override 
     protected Drawable doInBackground(Void... params) { 

      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpGet request = new HttpGet(_model.UserInfo.ProfileImageUrl); 

      InputStream inputStream = null; 

      try { 
       HttpResponse response = httpClient.execute(request);   
       inputStream = response.getEntity().getContent(); 
      } 
      catch (Exception e) {    
       Log.e("setUpUserInfo.doInBackground", e.getMessage()); 
      } 

      return Drawable.createFromStream(inputStream, "src"); 
     } 

     @Override 
     protected void onPostExecute(Drawable result) { 
      _profileImage.setImageDrawable(result); 
     } 
    } 
} 

Czy ktoś może dostrzec tu jakieś oczywiste problemy? Czy wyjątek od NetworkOnMainThreadException może zostać zgłoszony z jakiegokolwiek innego powodu niż wykonanie żądania http w wątku głównym?

Jestem nowym użytkownikiem Androida, pracowałem z nim tylko kilka dni.

Odpowiedz

22

ale jak widać w kodzie poniżej Jestem rzeczywiście wywołanie HTTP Get w AsyncTask

Nie jesteś, rzeczywiście. Musisz zadzwonić pod numer execute(), zamiast dzwonić pod numer doInBackground() bezpośrednio, w przeciwnym razie nie używasz żadnej z instalacji dostarczonej przez AsyncTask, a ty po prostu wywołujesz metodę bezpośrednio w wątku interfejsu użytkownika.

+0

Aha dziękuję, mój przyjacielu! – jcvandan

+0

Kilka razy potknąłem się o to i już prawie zrobiłem to z wątkami (Start vs. run). Dlaczego funkcja 'doInBackground()' jest dostępna nawet wtedy, gdy jest to bezużyteczne? –

+1

Uh ... co masz na myśli "dostępny"? Przede wszystkim jest "chroniony", co oznacza, że ​​nie powinno się go wywoływać z klasy spoza AsyncTask. Niestety, wiele osób po prostu deklaruje wbudowane AsyncTasks, aby mogli (i robią) wywoływać 'doInBackground()'. 'execute()' jednak * jest * 'publiczne'. – dmon

1

Może wersja Androida SDK jest wysoka (wersja> = 3.0).

Spróbuj dodać kod

import android.os.StrictMode;

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 
     .detectDiskReads() 
     .detectDiskWrites() 
     .detectNetwork() // or .detectAll() for all detectable problems 
     .penaltyLog() 
     .build()); 

w funkcji onCreateView();

+0

Dzięki człowieku ... pomógł !!!! – krisDrOid

+1

To jest zła praktyka. Dodano ten tryb, aby ludzie nie kodowali treści związanych z siecią w wątku interfejsu użytkownika. Jest to tylko jeden krok wyższy od hackowania. Kod poprawnie jest lepszym rozwiązaniem. – WORMSS