NetworkOnMainThreadException в AsyncTask
Я получаю NetworkOnMainThreadException
при выполнении двух сетевых запросов в AsyncTask
, В первом запросе я получаю Response XML
и во втором запросе я загружаю Image InputStream
быть использованным в BitmapFactory.decodeStream
, Пожалуйста, найдите ниже исключения:
NetworkOnMainThreadException
07-10 08:20:49.961: W/System.err(8570): android.os.NetworkOnMainThreadException
07-10 08:20:49.961: W/System.err(8570): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
07-10 08:20:49.961: W/System.err(8570): at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
07-10 08:20:49.971: W/System.err(8570): at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
07-10 08:20:49.971: W/System.err(8570): at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
07-10 08:20:49.971: W/System.err(8570): at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
07-10 08:20:49.971: W/System.err(8570): at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
07-10 08:20:49.981: W/System.err(8570): at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
AyncTask
public class FetchDataTask extends AsyncTask {
@Override
protected Object doInBackground(Object... object) {
String url = (String)object[0];
TASK_TYPE type = (TASK_TYPE)object[1];
Object[] objects = new Object[4];
switch(type)
{
case FETCH_NOTICES:
publishProgress("Fetching notices ...");
// Request # 1 to get the JSON XML
String data = apiRequestGET(url);
ArrayList<Notices> notices = extractUserFriendsDataFromXML(data);
Notices notice = notices.get(0);
publishProgress("Fetching done.");
objects[0] = type;
objects[1] = new ArrayList<Notices>(notices.subList(1, notices.size()));
objects[2] = notice.getUniversityTitle();
try {
// Request # 2 to get the InputStream
objects[3] = (InputStream) new URL(notice.getUniversityLogo()).getContent();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return objects;
}
return null;
}
private String apiRequestGET(String requestString)
{
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(requestString);
String responseText = null;
try
{
HttpResponse response = httpClient.execute(httpGet, localContext);
System.out.println("Some Response" +response);
HttpEntity entity = response.getEntity();
responseText = EntityUtils.toString(entity);
}
catch (Exception e1)
{
return e1.getLocalizedMessage();
}
return responseText;
}
}
Может кто-нибудь сказать, пожалуйста, что я делаю не так? Два сетевых запроса в doInBackground
не может быть сделано?
Заранее спасибо!
Изменить полную трассировку стека
07-10 08:52:18.672: W/System.err(9213): android.os.NetworkOnMainThreadException
07-10 08:52:18.682: W/System.err(9213): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
07-10 08:52:18.682: W/System.err(9213): at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
07-10 08:52:18.682: W/System.err(9213): at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
07-10 08:52:18.692: W/System.err(9213): at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
07-10 08:52:18.692: W/System.err(9213): at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
07-10 08:52:18.692: W/System.err(9213): at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
07-10 08:52:18.702: W/System.err(9213): at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
07-10 08:52:18.702: W/System.err(9213): at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
07-10 08:52:18.702: W/System.err(9213): at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:168)
07-10 08:52:18.702: W/System.err(9213): at java.io.BufferedInputStream.read(BufferedInputStream.java:309)
07-10 08:52:18.712: W/System.err(9213): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-10 08:52:18.712: W/System.err(9213): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
07-10 08:52:18.712: W/System.err(9213): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:601)
07-10 08:52:18.722: W/System.err(9213): at com.alpha.noticeslist.NoticeListActivity.dataFetched(NoticeListActivity.java:145)
07-10 08:52:18.722: W/System.err(9213): at com.alpha.web.FetchDataTask.onPostExecute(FetchDataTask.java:124)
07-10 08:52:18.732: W/System.err(9213): at android.os.AsyncTask.finish(AsyncTask.java:631)
07-10 08:52:18.732: W/System.err(9213): at android.os.AsyncTask.access$600(AsyncTask.java:177)
07-10 08:52:18.732: W/System.err(9213): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
07-10 08:52:18.732: W/System.err(9213): at android.os.Handler.dispatchMessage(Handler.java:99)
07-10 08:52:18.742: W/System.err(9213): at android.os.Looper.loop(Looper.java:137)
07-10 08:52:18.742: W/System.err(9213): at android.app.ActivityThread.main(ActivityThread.java:5041)
07-10 08:52:18.752: W/System.err(9213): at java.lang.reflect.Method.invokeNative(Native Method)
07-10 08:52:18.752: W/System.err(9213): at java.lang.reflect.Method.invoke(Method.java:511)
07-10 08:52:18.752: W/System.err(9213): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-10 08:52:18.752: W/System.err(9213): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-10 08:52:18.762: W/System.err(9213): at dalvik.system.NativeStart.main(Native Method)
Я получаю сообщение об ошибке при вызове функции из onPostExecute
в котором InputStream
передается как:
public void dataFetched(InputStream inputstream)
{
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
logo.setImageBitmap(bitmap);
}
onPostExecute
@Override
protected void onPostExecute(Object result){
statusDialog.dismiss();
Object[] objects = (Object[])result;
TASK_TYPE type = (TASK_TYPE)objects[0];
switch(type)
{
case FETCH_NOTICES:
((NoticeListActivity)callerActivity).dataFetched((InputStream)objects[3]);
break;
}
}
4 ответа
Я думаю, что вы получаете ошибку, потому что, хотя вы получаете ссылку на InputStream
в фоновом потоке вы фактически читаете из потока при вызове decodeStream
в onPostExecute
, который работает в основном потоке
Переместить звонок:
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
в doInBackground
и передать bitmap
назад, а не входящий поток
Ваш класс должен быть:
class FetchDataTask extends AsyncTask<Object, String, Void>
{
@Override
protected Void doInBackground(Object... params) {
//code here
publishProgress("");
return null;
}
@Override
protected void onProgressUpdate(String... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
}
вы можете выполнить как new FetchDataTask.execute([your parameter]);
Убедитесь, что вы звоните myFetchDataTask.execute()
, Ты звонишь doInBackground()
напрямую, если это так, то это не сработает, если нет, пожалуйста, напишите, как вы выполняете AsyncTask
,
Надеюсь, поможет!
Используйте приведенный ниже код для асинхронной задачи:
private class FetchDataTask extends AsyncTask <String, Void, Void>
{
Object[] objects = new Object[4];
protected void onPreExecute() {
}
@Override
protected Void doInBackground(String... paramsObj) {
String url = (String)object[0];
TASK_TYPE type = (TASK_TYPE)object[1];
switch(type)
{
case FETCH_NOTICES:
publishProgress("Fetching notices ...");
// Request # 1 to get the JSON XML
String data = apiRequestGET(url);
ArrayList<Notices> notices = extractUserFriendsDataFromXML(data);
Notices notice = notices.get(0);
publishProgress("Fetching done.");
objects[0] = type;
objects[1] = new ArrayList<Notices>(notices.subList(1, notices.size()));
objects[2] = notice.getUniversityTitle();
try {
// Request # 2 to get the InputStream
objects[3] = (InputStream) new URL(notice.getUniversityLogo()).getContent();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return null;
}
protected void onPostExecute(Void unused)
{
// Do action with objects
}
}
Из метода вызова используйте:
new FetchDataTask().execute();