2014-01-05 65 views
1

我很難嘗試將AsyncTask應用到我現有的代碼。如何使用現有代碼的異步任務

如此虐待開始說我的代碼工作正常,直到我調升我的目標SDK,而我得到了以下錯誤消息:

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

經過一番研究,看起來這是因爲我試圖在主線程上運行網絡操作,這是一個很大的禁忌。解決方法是使用異步任務來運行網絡操作。

好的,到目前爲止對我來說是有意義的,現在我所要做的就是以某種方式在我的代碼中實現異步任務,並且在這裏解決我的問題。

基本上,我有一個登錄屏幕,導致成功登錄的主頁(有點像Facebook)。當您單擊登錄按鈕時,它會向我的服務器上的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的返回需要返回響應,以便post執行方法可以使用它。 –

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