在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行时都会报错,这是因为Android在4.0以后为了防止应用的
ANR(aplication Not Response)异常,就针对此问题有两种解决的方法:
1.可以再Activity的onCreate()方法中加入这样一段代码,如下:
// 强制直接在UI线程中进行网络操作
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwo()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
2.一般情况我们应该这样做
启动一条子线程进行你的网络请求。
当然,如果你的应用程序执行的网络请求数据量很小的话,可以使用第一种方案
启动线程访问网络的方式也有多种:
(1)启用异步任务线程类去访问网络(GET方式请求网络)
我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话
mTask = new MyTask();
mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类
private class MyTask extends AsyncTask<String, Integer, String> {
//onPreExecute方法用于在执行后台任务前做一些UI操作
@Override
protected void onPreExecute() {
}
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
long total = entity.getContentLength();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count = 0;
int length = -1;
while ((length = is.read(buf)) != -1) {
baos.write(buf, 0, length);
count += length;
//调用publishProgress公布进度,最后onProgressUpdate方法将被执行
publishProgress((int) ((count / (float) total) * 100));
}
return new String(baos.toByteArray(), "UTF-8");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
//onProgressUpdate方法用于更新进度信息
@Override
protected void onProgressUpdate(Integer... progresses) {
}
//onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(String result) {
//这里返回的result为成功访问网络后获得的数据
mTask.cancel(true);
}
//onCancelled方法用于在取消执行中的任务时更改UI
@Override
protected void onCancelled() {
}
}
(2)启用异步任务线程类去访问网络(POST方式请求网络模拟登录)
我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话
mTask = new MyTask();
mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类
private class MyTask extends AsyncTask<String, Integer, String> {
//onPreExecute方法用于在执行后台任务前做一些UI操作
@Override
protected void onPreExecute() {
}
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
List parameters = new ArrayList();
//请求数据(代替了输出流)
parameters.add(new BasicNameValuePair("UserName",username));
parameters.add(new BasicNameValuePair("Password",psaaword));
HttpPost post = new HttpPost(params[0]);
post.setEntity(new UrlEncodedFormEntity(parameters,"utf-8"));
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
long total = entity.getContentLength();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count = 0;
int length = -1;
while ((length = is.read(buf)) != -1) {
baos.write(buf, 0, length);
count += length;
}
return new String(baos.toByteArray(), "UTF-8");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
//onProgressUpdate方法用于更新进度信息
@Override
protected void onProgressUpdate(Integer... progresses) {
}
//onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(String result) {
mTask.cancel(true);
}
//onCancelled方法用于在取消执行中的任务时更改UI
@Override
protected void onCancelled() {
}
}
上面的两种方法都是采用HttpClient进行网络的访问请求,我们还可以用HttpURLConnection进行网络的访问请求,样式都比较类似,这里不一一举例。
ANR(aplication Not Response)异常,就针对此问题有两种解决的方法:
1.可以再Activity的onCreate()方法中加入这样一段代码,如下:
// 强制直接在UI线程中进行网络操作
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwo()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
2.一般情况我们应该这样做
启动一条子线程进行你的网络请求。
当然,如果你的应用程序执行的网络请求数据量很小的话,可以使用第一种方案
启动线程访问网络的方式也有多种:
(1)启用异步任务线程类去访问网络(GET方式请求网络)
我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话
mTask = new MyTask();
mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类
private class MyTask extends AsyncTask<String, Integer, String> {
//onPreExecute方法用于在执行后台任务前做一些UI操作
@Override
protected void onPreExecute() {
}
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
long total = entity.getContentLength();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count = 0;
int length = -1;
while ((length = is.read(buf)) != -1) {
baos.write(buf, 0, length);
count += length;
//调用publishProgress公布进度,最后onProgressUpdate方法将被执行
publishProgress((int) ((count / (float) total) * 100));
}
return new String(baos.toByteArray(), "UTF-8");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
//onProgressUpdate方法用于更新进度信息
@Override
protected void onProgressUpdate(Integer... progresses) {
}
//onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(String result) {
//这里返回的result为成功访问网络后获得的数据
mTask.cancel(true);
}
//onCancelled方法用于在取消执行中的任务时更改UI
@Override
protected void onCancelled() {
}
}
(2)启用异步任务线程类去访问网络(POST方式请求网络模拟登录)
我们可以在activity中建一个MyTask的类,给MyTask定义一个名mTask,让后再要访问网络的地方加上一下两句话
mTask = new MyTask();
mTask.execute("http://www.baidu.com");//这里输入网址,然后在activity中加入一下的MyTask类
private class MyTask extends AsyncTask<String, Integer, String> {
//onPreExecute方法用于在执行后台任务前做一些UI操作
@Override
protected void onPreExecute() {
}
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
List parameters = new ArrayList();
//请求数据(代替了输出流)
parameters.add(new BasicNameValuePair("UserName",username));
parameters.add(new BasicNameValuePair("Password",psaaword));
HttpPost post = new HttpPost(params[0]);
post.setEntity(new UrlEncodedFormEntity(parameters,"utf-8"));
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
long total = entity.getContentLength();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count = 0;
int length = -1;
while ((length = is.read(buf)) != -1) {
baos.write(buf, 0, length);
count += length;
}
return new String(baos.toByteArray(), "UTF-8");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
//onProgressUpdate方法用于更新进度信息
@Override
protected void onProgressUpdate(Integer... progresses) {
}
//onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(String result) {
mTask.cancel(true);
}
//onCancelled方法用于在取消执行中的任务时更改UI
@Override
protected void onCancelled() {
}
}
上面的两种方法都是采用HttpClient进行网络的访问请求,我们还可以用HttpURLConnection进行网络的访问请求,样式都比较类似,这里不一一举例。