NetworkOnMainThreadException android活动

时间:2016-03-19 07:10:49

标签: android

我正在使用此代码检索android活动中的网站数据。它正在抛出android.os.networkonmainthreadexception

    try
        {
            URL url = new URL("https://enigmatic-woodland-35608.herokuapp.com/pager.json");
            URLConnection tc = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    tc.getInputStream()));
            String line, newl = " ";
            while ((line = in.readLine()) != null) {
                newl += line.trim();
            }
            System.out.println("newl" + newl.trim());
        } catch (Exception e) {
            Log.e("exception", e.toString());
        }

请给我一个可能的解决方案..

3 个答案:

答案 0 :(得分:3)

网络操作/调用无法在主线程中完成。您需要从另一个线程,异步任务或意向服务

运行它

注意:所有UI操作都应该在onPostExecute,onPreExecute上完成

以下代码可以帮助您解决。

在您想要的地方调用AsyncTask

new PagerAsyncTask().execute();

class PagerAsyncTask extends AsyncTask<String,Void,String>{
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

        @Override
        protected String doInBackground(String... params) {
            StringBuilder sb=null;
            BufferedReader reader=null;
            String serverResponse=null;
            try {

                URL url = new URL(""https://enigmatic-woodland-35608.herokuapp.com/pager.json"");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                connection.setConnectTimeout(5000);
                connection.setRequestMethod("GET");
                connection.connect();
                int statusCode = connection.getResponseCode();
                //Log.e("statusCode", "" + statusCode);
                if (statusCode == 200) {
                    sb = new StringBuilder();
                    reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                }

                connection.disconnect();
                if (sb!=null)
                    serverResponse=sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return serverResponse;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
           //All your UI operation can be performed here
            //Response string can be converted to JSONObject/JSONArray like
            JSONObject response=new JSONObject(s);
            System.out.println(s);
        }
    }

答案 1 :(得分:2)

  

网络运营可能涉及不可预测的延迟。为了防止这种情况   从导致糟糕的用户体验,始终执行网络操作   在与UI的单独线程上。

请查看doc

答案 2 :(得分:0)

我在我的项目中使用了NetworkOps工具。试试吧:

import android.content.Context;
import android.net.Uri;
import android.util.Log;

import com.csehelper.variables.Constants;
import com.csehelper.variables.Keys;
import com.csehelper.variables.Url;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;

public class NetworkOps {
    public final String EXCEPTION = "~Exception~";
    /****************************
     * Method to Grab Source
     ****************************/
    public static String GrabSource(String URL) {
        return PostData(URL, null);
    }



    /**
     * *****************************************
     * Method to Grab Source code from URL
     * Posting Data
     * *****************************************
     */
    private static String PostData(String url, Uri.Builder uribuilder) {
        String Source;
       HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection urlConnection = null;
        try {
            urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setConnectTimeout(10000);

            if(uribuilder != null) {
                String query = uribuilder.build().getEncodedQuery();

                OutputStream os = urlConnection.getOutputStream();
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(os, "UTF-8"));
                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
            }

            urlConnection.connect();

            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {

                String line;
                StringBuilder builder = new StringBuilder();
                InputStreamReader isr = new InputStreamReader(
                        urlConnection.getInputStream());
                BufferedReader reader = new BufferedReader(isr);
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
                Source = builder.toString();
            } else {
                Source = EXCEPTION + "Server unreachable. Check network connection.";
            }
        } catch (SocketTimeoutException e) {
            Source = EXCEPTION + "Connection timed out.";
        } catch (java.net.UnknownHostException e) {
            Source = EXCEPTION + Constants.EXCEPTION_NO_NET;
        } catch (ArrayIndexOutOfBoundsException e) {
            Source = EXCEPTION + "Server error";
        } catch (ProtocolException e) {
            Source = EXCEPTION + "Protocol error";
        } catch (IOException e) {
            Source = EXCEPTION + "Server unreachable. Check network connection.";
        } catch (Exception e) {
            Source = EXCEPTION + "Error:" + e.toString() + " - "
                    + e.getMessage();
            e.printStackTrace();

        } finally {
            if (urlConnection != null) urlConnection.disconnect();
        }
        return Source;
    }


}

从AsyncTask调用这些静态函数:

/*********************************
 * AsyncTask to GrabSource
 ********************************/
class AsyncTask_GrabSource extends AsyncTask<Void, Void, Void> {

    String Source = null;
    String url = "https://enigmatic-woodland-35608.herokuapp.com/pager.json";
    @Override
    protected void onPreExecute() {
       //Runs on Main Thread. You can access your UI elements here.
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Don't access any UI elements from this function
        Source = NetworkOps.GrabSource(this.url);
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        if (Source != null) {
            if (!Source.contains(EXCEPTION)) {
                //Show Error Message or do whatever you want
            } else {
                //Do Whatever with your Grabbed Sourcecode.
                // This function runs on UI Thread, so you can update UI elements here
            }

    }
}

您还可以使用PostData函数发布数据。在方法doInBackground中,添加:

Uri.Builder builder = new Uri.Builder()
                    .appendQueryParameter("key", "value")
                    .appendQueryParameter("key2", "value2");

Source = NetworkOps.PostData(getApplicationContext(), url, builder);