如何通过NetworkOnMainThreadException异常我进入我的代码?

时间:2014-07-17 11:19:08

标签: android web-services android-asynctask networkonmainthread

我再次陷入困境需要你们的帮助。我在获取服务响应时收到NetworkOnMainThreadException异常。我还在学习Android,所以不知道Android中线程的坚定后果。任何有关解释和工作示例的帮助都会很棒。在此先感谢,你们真是太棒了。

package com.abcd.myapp;

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.HttpStatus;
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 android.util.Log;

public class RequestManager {

    String baseUrl = "http://dev.mysite.com/Service/MyService.svc/";

    public String GetResponse(String url) {
        String responseText = "";
        // Create a HTTP client 
        HttpClient httpClient = new DefaultHttpClient(); 
        HttpGet httpGet = new HttpGet(baseUrl + url);

        try {
            // get the response 
            HttpResponse response = httpClient.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                InputStream is = entity.getContent();               
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
                // Create a buffer 
                StringBuilder sb = new StringBuilder();

                String line;
                while((line = reader.readLine()) != null) {                 
                    sb.append(line + "\n");
                }

                is.close();
                responseText = sb.toString();
                // do something with response 
            } else {
                Log.d("RequestManager", "Error fetching data. Server returned status code: {0}"+ statusLine.getStatusCode());
                // handle bad response
            }
        } catch (ClientProtocolException e) {
            // handle exception
             e.printStackTrace(); 
        } catch (IOException e) {
            // handle exception
             e.printStackTrace(); 
        }
        return responseText.toString(); 
    }
}

我的活动类:

package com.abcd.myapp;

import java.util.HashSet;
import java.util.Set;

import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class CheckEmailActivity  extends Activity {

    EditText txtEmail;
    Button btnGo;

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

        setContentView(R.layout.check_email);
        btnGo = (Button) findViewById (R.id.btnGo);
        txtEmail = (EditText)findViewById (R.id.tbCheckEmail);
        btnGo.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(txtEmail.getWindowToken(), 0);

                if (TextUtils.isEmpty(txtEmail.getText()))
                {
                    String msg = "Oops! Please enter your email.";
                    Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
                }
                else
                {
                    String email = txtEmail.getText().toString().toLowerCase();
                    String response = "";
                    RequestManager rm = new RequestManager();
                    String x = "";

                    try
                    {
                        String url = "CheckEmail///" + email;
                        response = rm.GetResponse(url);
                        JSONObject obj = new JSONObject(response);

                        x = obj.getString("CheckEmailResult");
                        if (x == "1")
                        {
                            //Send Confirmation Email
                            String msg = "Please check your email.";

                            SharedPreferences prefAccount = getApplicationContext().getSharedPreferences("CoDiAccount", Context.MODE_PRIVATE);

                            Set<String> newq = new HashSet<String>();
                            newq = prefAccount.getStringSet("Accounts", newq);
                            Editor prefEditorAccount = prefAccount.edit();
                            prefEditorAccount.putString("email", email);                        
                            newq.add(email);
                            prefEditorAccount.putStringSet("Accounts", (Set<String>) newq);
                            prefEditorAccount.commit();
                            String directoryname = "CoDiApp" + email;
                            SharedPreferences prefs = getApplicationContext().getSharedPreferences(directoryname, Context.MODE_PRIVATE);

                            Editor prefEditor = prefs.edit();
                            prefEditor.putString("login", "0");
                            prefEditor.putString("email", email);
                            prefEditor.commit();
                            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();

                            //Validate account
                            Intent verifyAccount = new Intent(CheckEmailActivity.this, VerifyAccountActivity.class);
                            startActivity(verifyAccount);
                        }
                        else
                        {
                            String msg = "Sorry, Your email address  not found.";
                            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
                        }
                    }
                    catch (Exception ex)
                    {
                        response = ex.getMessage().toString();
                        String msg = "Network is unavailable. Please try again later." + response;
                        AlertDialog.Builder builder = new AlertDialog.Builder(CheckEmailActivity.this);
                        builder.setMessage(msg)
                               .setCancelable(false)
                               .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                   public void onClick(DialogInterface dialog, int id) {
                                        //do things
                                   }
                               });
                        AlertDialog alert = builder.create();
                        alert.setTitle("Re-Try");
                        alert.show();
                    }
                }
            }
        }) ;           
    } 

2 个答案:

答案 0 :(得分:0)

您应该在异步任务中进行http调用,并为清单添加INTERNET权限。

您可以从此处获取有关异步任务的一些信息:http://developer.android.com/reference/android/os/AsyncTask.html

Ps:当我有时间时,我会编辑我的答案并给出代码样本。

答案 1 :(得分:0)

您无法在主/ UI线程上执行网络操作。你应该使用AsyncTask 代替。修改您的方法如下:

String response;

public String GetResponse(String url) {
  String responseText = "";
        // Create a HTTP client 
        HttpClient httpClient;
        HttpGet httpGet;
    AsyncTask<String, Void, String> myAsyncTask = new AsyncTask<String, Void, String>() {
        @Override
        protected void onPreExecute() {

            super.onPreExecute();
         httpClient = new DefaultHttpClient(); 
    httpGet = new HttpGet(baseUrl + url);
        }

        @Override
        protected String doInBackground(String... params) {
             try {
        // get the response 
        HttpResponse response = httpClient.execute(httpGet);
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();               
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            // Create a buffer 
            StringBuilder sb = new StringBuilder();

            String line;
            while((line = reader.readLine()) != null) {                 
                sb.append(line + "\n");
            }

            is.close();
            responseText = sb.toString();
            // do something with response 
        } else {
            Log.d("RequestManager", "Error fetching data. Server returned status code: {0}"+ statusLine.getStatusCode());
            // handle bad response
        }
    } catch (ClientProtocolException e) {
        // handle exception
         e.printStackTrace(); 
    } catch (IOException e) {
        // handle exception
         e.printStackTrace(); 
    }
    return responseText.toString();

        }

        @Override
        protected void onPostExecute(String result) {
            response = result;
        }

    };//
    myAsyncTask.execute("");
}

您无法在主/ UI线程上执行网络操作。你应该使用AsyncTask 代替。修改您的方法如下:

<强>更新

异步任务是异步的,因此在后台独立于程序当前UI线程执行。所以在线:

 response = rm.GetResponse(url);
  JSONObject obj = new JSONObject(response);

可以在GetResponse()中获取响应之前构造JSONObject 因为它在UI线程上执行,所以在onPostExecute中使用结果。您可以在活动类中使用此方法:

//活动类中的新方法,用于获取结果并处理它

您的活动类:

String response;

public String getResponseAndProcess(String url) {
  String responseText = "";
        // Create a HTTP client 
        HttpClient httpClient;
        HttpGet httpGet;
    AsyncTask<String, Void, String> myAsyncTask = new AsyncTask<String, Void, String>() {
        @Override
        protected void onPreExecute() {

            super.onPreExecute();
         httpClient = new DefaultHttpClient(); 
    httpGet = new HttpGet(baseUrl + url);
        }

        @Override
        protected String doInBackground(String... params) {
             try {
        // get the response 
        HttpResponse response = httpClient.execute(httpGet);
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();               
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            // Create a buffer 
            StringBuilder sb = new StringBuilder();

            String line;
            while((line = reader.readLine()) != null) {                 
                sb.append(line + "\n");
            }

            is.close();
            responseText = sb.toString();
            // do something with response 
        } else {
            Log.d("RequestManager", "Error fetching data. Server returned status code: {0}"+ statusLine.getStatusCode());
            // handle bad response
        }
    } catch (ClientProtocolException e) {
        // handle exception
         e.printStackTrace(); 
    } catch (IOException e) {
        // handle exception
         e.printStackTrace(); 
    }
    return responseText.toString();

        }

        @Override
        protected void onPostExecute(String result) {
             try
                {
                    JSONObject obj = new JSONObject(result);

                    x = obj.getString("CheckEmailResult");
                    if (x == "1")
                    {
                        //Send Confirmation Email
                        String msg = "Please check your email.";

                        SharedPreferences prefAccount = getApplicationContext().getSharedPreferences("CoDiAccount", Context.MODE_PRIVATE);

                        Set<String> newq = new HashSet<String>();
                        newq = prefAccount.getStringSet("Accounts", newq);
                        Editor prefEditorAccount = prefAccount.edit();
                        prefEditorAccount.putString("email", email);                        
                        newq.add(email);
                        prefEditorAccount.putStringSet("Accounts", (Set<String>) newq);
                        prefEditorAccount.commit();
                        String directoryname = "CoDiApp" + email;
                        SharedPreferences prefs = getApplicationContext().getSharedPreferences(directoryname, Context.MODE_PRIVATE);

                        Editor prefEditor = prefs.edit();
                        prefEditor.putString("login", "0");
                        prefEditor.putString("email", email);
                        prefEditor.commit();
                        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();

                        //Validate account
                        Intent verifyAccount = new Intent(CheckEmailActivity.this, VerifyAccountActivity.class);
                        startActivity(verifyAccount);
                    }
                    else
                    {
                        String msg = "Sorry, Your email address  not found.";
                        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
                    }
                }
                catch (Exception ex)
                {
                    response = ex.getMessage().toString();
                    String msg = "Network is unavailable. Please try again later." + response;
                    AlertDialog.Builder builder = new AlertDialog.Builder(CheckEmailActivity.this);
                    builder.setMessage(msg)
                           .setCancelable(false)
                           .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    //do things
                               }
                           });
                    AlertDialog alert = builder.create();
                    alert.setTitle("Re-Try");
                    alert.show();
                }
            }

        }

    };//
    myAsyncTask.execute("");
}

然后在onClick():

btnGo.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(txtEmail.getWindowToken(), 0);

            if (TextUtils.isEmpty(txtEmail.getText()))
            {
                String msg = "Oops! Please enter your email.";
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
            }
            else
            {
                String email = txtEmail.getText().toString().toLowerCase();
                String x = "";
                String url = "CheckEmail///" + email;
                getResponseAndProcess(url);
              }
    }) ;           
}