在android中使用Jackson的android.os.NetworkOnMainThreadException

时间:2014-08-09 17:09:02

标签: android networkonmainthread

我的问题是android.os.NetworkOnMainThreadException。我已经在堆栈溢出中看了一些答案,但我无法解决它。

08-09 17:15:57.066: E/AndroidRuntime(6285): FATAL EXCEPTION: main
08-09 17:15:57.066: E/AndroidRuntime(6285): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.itechtc.curtamais/br.com.itechtc.curtamais.activities.MainActivity}: android.os.NetworkOnMainThreadException
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2073)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2098)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread.access$600(ActivityThread.java:138)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1204)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.os.Looper.loop(Looper.java:137)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread.main(ActivityThread.java:4945)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.lang.reflect.Method.invokeNative(Native Method)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.lang.reflect.Method.invoke(Method.java:511)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at dalvik.system.NativeStart.main(Native Method)
08-09 17:15:57.066: E/AndroidRuntime(6285): Caused by: android.os.NetworkOnMainThreadException
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.net.InetAddress.lookupHostByName(InetAddress.java:425)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:276)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.net.InetAddress.getAllByName(InetAddress.java:250)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpEngine.connect(HttpEngine.java:310)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at java.net.URL.openStream(URL.java:462)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at org.codehaus.jackson.JsonFactory._optimizedStreamFromURL(JsonFactory.java:935)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:530)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1593)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at br.com.itechtc.curtamais.business.PublicidadeBO.converterJson(PublicidadeBO.java:31)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at br.com.itechtc.curtamais.business.PublicidadeBO.<init>(PublicidadeBO.java:19)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at br.com.itechtc.curtamais.fragments.HomeFragment$CarregaDadosCaller.onPreExecute(HomeFragment.java:265)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.os.AsyncTask.execute(AsyncTask.java:534)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at br.com.itechtc.curtamais.fragments.HomeFragment.onCreateView(HomeFragment.java:57)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:571)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1166)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.Activity.performStart(Activity.java:5212)
08-09 17:15:57.066: E/AndroidRuntime(6285):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2046)
08-09 17:15:57.066: E/AndroidRuntime(6285):     ... 11 more

首先,我使用Jackson将JSON的信息绑定到Java对象中。有人因为杰克逊已经遇到过NetworkOnMainThread的问题吗?

我将这种方式转换为PublicidadeBO类:

public PublicidadeBO(String url) {
    // TODO Auto-generated constructor stub
    converterJson(url);
}

public void convertToJson(String url) {
     lista = new ArrayList<Publicidade>();
    try {
        ObjectMapper mapper = new ObjectMapper();
        lista = mapper.readValue(new URL(url), mapper.getTypeFactory().constructCollectionType(List.class, Publicidade.class));
    } catch (IOException e) {
        Log.i("json", "Erro no JSON");
        e.printStackTrace();
    }
}

然后在另一个Activity类中:

private class CarregaDadosCaller extends AsyncTask<Void, Void, Void> {
    private PublicidadeBO publicidade; 
    private EventoBO evento; 

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        publicidade = new PublicidadeBO("http://urlhere");
        evento = new EventoBO("http://urlhere");
        carregaDados();
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        return null;
    }

    public void carregaDados() {
        String publicidadeUrl = publicidade.concatenarUrlComSlug("http://urlhere");
        evento.popularListaImagemChamada("http://urlhere");
        evento.popularListaTitulo();
    }
    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        ImageViewTask taskImageView = new ImageViewTask();  
        taskImageView.execute(publicidadeUrl);

        ImageSwitcherTask taskImageSwitcher = new ImageSwitcherTask();
        String[] strArray = evento.getLinksEvento().toArray(new String[0]);
        taskImageSwitcher.execute(strArray);

        super.onPostExecute(result);
    }
}

提前致谢。

2 个答案:

答案 0 :(得分:2)

您应该在后台线程中执行网络请求carregaDados()。 您可以使用AsyncTask的doInBackground方法执行此操作。

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected Void doInBackground(Void... params) {
    publicidade = new PublicidadeBO("http://urlhere");
    evento = new EventoBO("http://urlhere");
    carregaDados();
    return null;
}

顺便说一句,你应该使用AsyncTask返回值。

答案 1 :(得分:0)

Necesitas mover el metodo de cargarDatos()a doInBackground();
您需要将cargarDatos()方法移动到doInBackground();

@Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        publicidade = new PublicidadeBO("http://urlhere");
        evento = new EventoBO("http://urlhere");
//        carregaDados(); This Code is commented
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        carregaDados();///Line addded
        return null;
    }