我再次陷入困境需要你们的帮助。我在获取服务响应时收到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();
}
}
}
}) ;
}
答案 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);
}
}) ;
}