2012-04-10 2 views
0

동료의 stackflower 코드가 생겨서 어떤 이유로 응용 프로그램이 비정상적으로 작동하고 Async에 익숙하지 않아 많은 디버깅 경험이 없습니다. HttPost를 통해 데이터를 다운로드하고 간단한 목록보기로 데이터를 나열하려고합니다.Async DoInBackground Listview에서 충돌이 발생했습니다.

코드 :

public class ChatService extends ListActivity { 
    /** Called when the activity is first created. */ 

    BufferedReader in = null; 
    String data = null; 
    List headlines; 
    List links; 
    String GotPass; 
    ArrayAdapter adapter; 
    String GotUname; 
    public static final String PREFS_NAME ="MyPregs"; 
    private GetTask getTask; 
    public ListView fList; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     getTask = new GetTask(); 
     getTask.execute(); 

     ArrayAdapter adapter = new ArrayAdapter(this, 
       android.R.layout.simple_list_item_1, headlines); 
    } 

    public class GetTask extends AsyncTask<Void, Void, List> 
    { 
     @Override 
     protected List doInBackground(Void... params) { 
     return load(); 
     }  

     @Override 
     protected void onPostExecute(List result) { 


     fList.setAdapter(adapter); 
     } 
    } 

    private List load() { 
     // get your data from http 
     // add to your list, probably you can use model. 
     BufferedReader in = null; 
     String data = null; 
     Bundle gotData = getIntent().getExtras(); 
     if(gotData != null) 
     { 
      GotPass = gotData.getString("key!"); 
      GotUname = gotData.getString("key!!"); 
     } 
     SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); 
     String username = settings.getString("key1", null); 
     String password = settings.getString("key2", null); 
     if(username.equals("irock97")) { 
      Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show(); 
     } else { 
      Toast.makeText(getApplicationContext(), "fail", Toast.LENGTH_SHORT).show(); 
     } 

     HttpClient httpclient = new DefaultHttpClient(); 

     /* login.php returns true if username and password is equal to saranga */ 
     HttpPost httppost = new HttpPost("http://gta5news.com/login.php"); 

     try { 
      // Add user name and password 
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      nameValuePairs.add(new BasicNameValuePair("username", username)); 
      nameValuePairs.add(new BasicNameValuePair("password", password)); 
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

      // Execute HTTP Post Request 
      Log.w("HttpPost", "Execute HTTP Post Request"); 
      HttpResponse response = httpclient.execute(httppost); 
      in = new BufferedReader(new InputStreamReader(response.getEntity() 
        .getContent())); 
      StringBuffer sb = new StringBuffer(""); 
      String l =""; 
      String nl =""; 
      while ((l =in.readLine()) !=null) { 
       sb.append(l + nl); 
      } 
      in.close(); 
      data = sb.toString(); 

      ListView lv = getListView(); 
      lv.setTextFilterEnabled(true); 

      headlines.add(data); 




      ArrayAdapter adapter = new ArrayAdapter(this, 
        android.R.layout.simple_list_item_1, headlines); 

      setListAdapter(adapter); 


     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return headlines; 
    } 

    private StringBuilder inputStreamToString1(InputStream is) { 
     String line = ""; 
     StringBuilder total = new StringBuilder(); 
     // Wrap a BufferedReader around the InputStream 
     BufferedReader rd = new BufferedReader(new InputStreamReader(is)); 
     // Read response until the end 
     try { 
      while ((line = rd.readLine()) != null) { 
       total.append(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     // Return full string 
     return total; 
    } 




    } 

로그 캣 : doInbackground에서

04-10 20:47:18.526: E/AndroidRuntime(574): FATAL EXCEPTION: AsyncTask #1 
04-10 20:47:18.526: E/AndroidRuntime(574): java.lang.RuntimeException: An error occured while executing doInBackground() 
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.lang.Thread.run(Thread.java:1096) 
04-10 20:47:18.526: E/AndroidRuntime(574): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.Handler.<init>(Handler.java:121) 
04-10 20:47:18.526: E/AndroidRuntime(574): at android.widget.Toast.<init>(Toast.java:68) 
04-10 20:47:18.526: E/AndroidRuntime(574): at android.widget.Toast.makeText(Toast.java:231) 
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService.load(ChatService.java:97) 
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService.access$0(ChatService.java:82) 
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService$GetTask.doInBackground(ChatService.java:71) 
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService$GetTask.doInBackground(ChatService.java:1) 
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 

답변

2
You are calling Toast in load() function which is in DoInBackground. 
Toast messages touches UI thread which you can't do that. 

This line makes it crash. 
Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show(); 

Change you load function signature: 
This is your function: 
private List load() { 

don't return a list, create a modal container and return it like: 
private ReturnModel load() { 

and create a modal like this, and set and get this modal: 
and in your load function,fill this returnmodal, set passworderror true or false instead of toast message, and onpostexecute function, check password error and do your toast message there. 




package com.nesim.test; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 

import android.app.ListActivity; 
import android.content.SharedPreferences; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 

public class ChatService extends ListActivity { 
    String GotPass; 
    String GotUname; 
    public static final String PREFS_NAME = "MyPregs"; 
    private GetTask getTask; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    getTask = new GetTask(); 
    getTask.execute(); 
    } 

    public class GetTask extends AsyncTask<Void, Void, ReturnModel> { 
    @Override 
    protected ReturnModel doInBackground(Void... params) { 
     return load(); 
    } 

    @Override 
    protected void onPostExecute(ReturnModel result) { 

     if(result.passworderror == true) 
     { 
     Toast.makeText(getApplicationContext(), "fail", Toast.LENGTH_SHORT).show(); 
     } 
     else 
     { 
     Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show(); 

     ListView lv = getListView(); 
     lv.setTextFilterEnabled(true); 

     ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, result.getheadlines()); 
     setListAdapter(adapter); 
     } 
    } 
    } 

    private ReturnModel load() { 
    ReturnModel returnModel = new ReturnModel(); 

    BufferedReader in = null; 
    String data = null; 
    Bundle gotData = getIntent().getExtras(); 
    if (gotData != null) { 
     GotPass = gotData.getString("key!"); 
     GotUname = gotData.getString("key!!"); 
    } 

    SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); 
    String username = settings.getString("key1", null); 
    String password = settings.getString("key2", null); 
    // username = "irock97"; // unremark to test like you got username from prefs.. 
    if (username != null && username.equals("irock97")) { 
     returnModel.setPassworderror(false); 
    } 
    else 
    { 
     returnModel.setPassworderror(true); 
     return returnModel; 
    } 

    HttpClient httpclient = new DefaultHttpClient(); 

    /* login.php returns true if username and password is equal to saranga */ 
    HttpPost httppost = new HttpPost("http://gta5news.com/login.php"); 

    try { 
     // Add user name and password 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
     nameValuePairs.add(new BasicNameValuePair("username", username)); 
     nameValuePairs.add(new BasicNameValuePair("password", password)); 
     httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

     // Execute HTTP Post Request 
     Log.w("HttpPost", "Execute HTTP Post Request"); 
     HttpResponse response = httpclient.execute(httppost); 
     in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
     StringBuffer sb = new StringBuffer(""); 
     String l = ""; 
     String nl = ""; 
     while ((l = in.readLine()) != null) { 
     sb.append(l + nl); 
     } 
     in.close(); 
     data = sb.toString(); 


     List<String> headlines = new ArrayList<String>(); 
     headlines.add(data); 
     returnModel.setheadlines(headlines); 
    } 
    catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return returnModel; 
    } 


    public class ReturnModel { 
    private List<String> headlines; 
    private boolean passworderror; 

    public List<String> getheadlines() { 
     return headlines; 
    } 

    public void setheadlines(List<String> headlines) { 
     this.headlines = headlines; 
    } 

    public boolean getPassworderror() { 
     return passworderror; 
    } 

    public void setPassworderror(boolean passworderror) { 
     this.passworderror = passworderror; 
    } 
    } 

} 
+0

해당 줄을 제거하더라도 여전히 충돌이 발생합니다. – TheBlueCat

+0

EDIT1 : 업데이트 된 설명을 볼 수 있지만 코드는 아직 이해할 수 없습니다. – TheBlueCat

+0

다시 업데이트하려고했습니다. basicaly는 List와 기타 필드를 포함하는 간단한 컨테이너를 생성하여 loginerror 등을 유지하고로드 함수에서 onpostexecute로 해당 모달을 채 웁니다. –

0
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 

통화 Looper.Prepare()()

편집 : 어쨌든, 여기에 코드와 로그 캣입니다 또한 다른 모든 사람들이 알 수 있듯이 UI 스레드에서 Toast를 실행해야합니다.

+0

방금 ​​시도했지만 여전히 충돌합니다. 새 logcat으로 스레드를 업데이트해야합니까? – TheBlueCat

+0

Looper.Prepare()를 추가했는데 여전히 충돌이 발생하고, vies를 생성 할 때 Thread 오류가 발생하면 kailoon이 말한 것을 따르고 runOnUIThread() 함수도 사용하십시오. – jsimpson

0

이 오류는 일반적으로 UI 스레드 외부에서 UI를 수정하려고 할 때 발생합니다. 보고있는 오류는 Toast.makeText() 호출로 인해 발생합니다.

runOnUiThread(new Runnable() { 
    public void run() { 
     Toast.makeText(/* etc */).show(); 
    } 
} 
0

당신은하지 메인 UI 스레드에서 Toast.makeText을 요구하고있다 : 당신은 그것을 다시 쓸 수 있습니다. 이 스택 트레이스에 기록되면

:

Looper.prepare라고하지 스레드 내부 핸들러를 만들 수 없습니다(). 내부적으로 Toast.makeText는 자체적으로 사용하기 위해 처리기를 생성합니다.

테스트 목적으로 사용하는 경우 Log.v 또는 그와 유사한 것을 사용하는 것이 좋습니다. 당신이 정말로 토스트를 확인하려면

, 다음 runOnUIThread(), 또는 더 나은 사용하려고 :

publishProgress (...)를;

onProgressUpdate() AsyncTasks에서 사용할

.

관련 문제