2014-01-05 2 views
1

기존 코드에 AsyncTask을 적용하는 데 문제가 있습니다. 내 목표 SDK를 올렸다 때까지 내 코드가 잘 작동되었고, 나는 다음과 같은 오류 메시지가 도착 말하면서기존 코드에 비동기 작업을 사용하는 방법

그래서 아프지 시작 : 나는 때문에이 같은 몇 가지 조사 후

android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)

, 그것은 보인다 커다란 no-no 인 주 스레드에서 네트워크 작업을 실행하려고합니다. 이를 해결하기 위해 비동기 작업을 사용하여 네트워크 작업을 실행합니다.

좋아, 지금까지 내가 지금해야 할 일은 어쨌든 내 코드에 비동기 작업을 구현하는 것 뿐이다. 여기에 내 문제가있다.

기본적으로 성공적인 로그인시 홈페이지로 연결되는 로그인 화면이 있습니다 (페이스 북과 비슷합니다). 로그인 버튼을 클릭하면 내 서버의 PHP 파일에 HTTP 요청을 전송하여 로그인/비밀번호를 확인하고 응답을 되돌려 보냅니다. 이 응답을 기반으로 로그인합니다 (또는 "잘못된 로그인"응답을 제공합니다).

그래서 나는 이것이 범인이라고 확신합니다. 이제 제 질문은, 어떻게이 작업을 Asynch? 나는 코드를 작성하는 사람을 찾고 있지 않다. 나는 이것을 시작하는 방법에 대한 지침을 찾고있다. 나는 지금 며칠 동안이 일을하고 있으며, 팔에 서있다. (.

여기

public class AndroidLogin extends Activity implements OnClickListener { 


    Button ok,back,exit; 
    TextView result; 




    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 



     // Login button clicked 
     ok = (Button)findViewById(R.id.btn_login); 
     ok.setOnClickListener(this); 


     result = (TextView)findViewById(R.id.tbl_result); 



    } 









    public void postLoginData() { 

     // Add user name and password 
     EditText uname = (EditText)findViewById(R.id.txt_username); 
      String username = uname.getText().toString(); 

     EditText pword = (EditText)findViewById(R.id.txt_password); 
     String password = pword.getText().toString(); 

     // Create a new HttpClient and Post Header 
     HttpClient httpclient = new DefaultHttpClient(); 


     // login.php returns true if username and password match in db 
     HttpPost httppost = new HttpPost("http://www.alkouri.com/android/login.php?username=" + username + "&password=" + password ); 

     try { 






      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("SENCIDE", "Execute HTTP Post Request"); 
      HttpResponse response = httpclient.execute(httppost); 

      String str = inputStreamToString(response.getEntity().getContent()).toString(); 
      Log.w("SENCIDE", str); 

      if(str.toString().equalsIgnoreCase("true")) 
      { 
       Log.w("SENCIDE", "TRUE"); 
       result.setText("Login Successful! Please Wait..."); 
      }else 
      { 
       Log.w("SENCIDE", "FALSE"); 
       result.setText(str);     
      } 

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

    private StringBuilder inputStreamToString(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; 
    } 

    //when register button is clicked 
    public void RegisterButton(View view) { 
     Intent myIntent = new Intent(AndroidLogin.this, Registration.class); 
     AndroidLogin.this.startActivity(myIntent); 

    } 







    protected void onPostExecute(Void v){ 
     // turns the text in the textview "Tbl_result" into a text string called "tblresult" 
     TextView tblresult = (TextView) findViewById(R.id.tbl_result); 
     // If "tblresult" text string matches the string "Login Successful! Please Wait..." exactly, it will switch to next activity 
      if (tblresult.getText().toString().equals("Login Successful! Please Wait...")) { 
       Intent intent = new Intent(); 
       //take text in the username/password text boxes and put them into an extra and push to next activity 
       EditText uname2 = (EditText)findViewById(R.id.txt_username); 
       String username2 = uname2.getText().toString(); 
       EditText pword2 = (EditText)findViewById(R.id.txt_password); 
       String password2 = pword2.getText().toString(); 
       intent.putExtra("username2", username2 + "&pword=" + password2); 
       startActivity(intent); 
       }  
    } 













    public void onClick(View view) { 

     class PostLogingDataTask extends AsyncTask<Void,Void,Void> 
     { 
      protected Void doInBackground (Void... t) 
      { 
       postLoginData(); 
       return null; 





      } 



      } 

       new PostLogingDataTask().execute(); 
    } 


} 

나는 점점 오전 오류입니다 :

여기

내 로그인 클래스에 코드, 당신은 바닥에 내 비동기를 볼 수 있습니다

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

+0

코드에는 AsyncTask를가 없습니다에 핸들러를 사용합니다. – Raghunandan

+0

방금 ​​코드를 수정했습니다. 내부에 비동기 태스크를 넣었습니다. @Raghunandan – user3155326

+0

nnackground 스레드에서 ui를 업데이트/액세스 할 수 없습니다. 그래서 예외가 발생하는 이유는 – Raghunandan

답변

0
 public void onClick(View view) { 

    class PostLogingDataTask extends AsyncTask<Void,Void,Void> 
    { 
     protected Void doInBackground (Void... t) 
     { 
      postLoginData(); 
     } 


      protected void onPostExecute(Void v){ 
      // turns the text in the textview "Tbl_result" into a text string called "tblresult" 
      TextView tblresult = (TextView) findViewById(R.id.tbl_result); 
      // If "tblresult" text string matches the string "Login Successful! Please Wait..." exactly, it will switch to next activity 
       if (tblresult.getText().toString().equals("Login Successful! Please Wait...")) { 
         Intent intent = new Intent(this, Homepage.class); 
        //take text in the username/password text boxes and put them into an extra and push to next activity 
         EditText uname2 = (EditText)findViewById(R.id.txt_username); 
         String username2 = uname2.getText().toString(); 
         EditText pword2 = (EditText)findViewById(R.id.txt_password); 
         String password2 = pword2.getText().toString(); 
         intent.putExtra("username2", username2 + "&pword=" + password2); 
         startActivity(intent); 
        }  
     } 
     } 

      new PostLogingDataTask().execute(); 
} 
+0

입니다. 주 화면에 textview의 setText를 놓지 않으면 ...이 작업은 효과가 없습니다. onPostExecute' http://developer.android.com/reference/android/os/AsyncTask.html –

+0

게시물을 편집했습니다. onPostExecute를 사용하여 UI 스레드를 업데이트하십시오. – AndRSoid

+0

또 다른 주석 - onPostExecute는 asynctask 클래스 내부에 있어야하며 doInBackground의 리턴은 응답을 반환해야 포스트 실행 메소드가이 메소드와 함께 작동 할 수 있습니다. –

0

를 사용하여 스레드가 네트워크 활동을하고 UI 스레드

new Thread(new runnable(){ 
    @Override 
    public void run() { 
     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("SENCIDE", "Execute HTTP Post Request"); 
     HttpResponse response = httpclient.execute(httppost); 

     String str = inputStreamToString(response.getEntity().getContent()).toString(); 
     Log.w("SENCIDE", str); 
     Message msg = new Message(); 
     Bundle bundle = new Bundle(); 
     bundle.putString("str",str); 
     msg.setData(bundle); 
     handler.sendMessage(msg); 
    } 
}).start(); 

Handler handler = new Handler() { 
    public void handleMessage(Message msg) { 
    super.handleMessage(msg); 
     str = msg.getData().getString("str"); 
     if(str.toString().equalsIgnoreCase("true")) 
     { 
      Log.w("SENCIDE", "TRUE"); 
      result.setText("Login Successful! Please Wait..."); 
     }else 
     { 
      Log.w("SENCIDE", "FALSE"); 
      result.setText(str);     
     } 
    } 
}; 
+0

이 작업을 사용하거나 비동기 작업을 사용하는 것의 차이점은 무엇입니까? – user3155326

+0

차이가 없습니다.하지만 스레드를 사용하면 네트워크 작업 만 수행하고 UI를 변경해야 할 경우 사용 핸들러가 필요합니다. – henry4343

관련 문제