0

So I have a class with the following:

class NetworkRequest extends AsyncTask<String, StringBuilder, String> {

     @Override
    public String doInBackground(String... urls) {

        try
        {
            URL url = new URL(urls[0]);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            InputStream inputStream = url.openStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuilder stringBuilder = new StringBuilder();
            int cp;
            while ((cp = bufferedReader.read()) != -1)
            {
                stringBuilder.append((char) cp);
            }

            return stringBuilder.toString();
        }
        catch(Exception ex)
        {
            return null;
        }
    }

    public void onPostExecute(String string)
    {

    }
}

And it is being called here:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mediated);
    TextView welcome_txt = (TextView) findViewById(R.id.test_view);
    new NetworkRequest().execute("https://graph.facebook.com/me");
    NetworkRequest networkRequest = new NetworkRequest();
    String string = networkRequest.doInBackground();
    test_view.setText(string);
}

When this is executed I am returning with "nothing" which explains it is falling in the catch statement of the doInBackground method, I get an exception of:

android.os.NetworkOnMainThreadException

Does anyone understand what I am doing wrong?

Gusinator
  • 1
  • 2
  • 1
    You are directly calling the doInBackground method on your main thread. Normally this method is run by doing the execute, which you are already doing... – Edward van Raak Jun 10 '15 at 20:49
  • NetworkRequest networkRequest = new NetworkRequest(); String string = networkRequest.doInBackground(); return string; remove those three lines. And implement a decent onPostExecute where you set the result of doInBackgroud in your textview. – greenapps Jun 10 '15 at 21:01
  • AsyncTask change that to AsyncTask – greenapps Jun 10 '15 at 21:02
  • @greenapps This is what i was initially thinking but i cannot seem to understand how to return a string from the onPostExecute to the onCreate so it can be formatted to be shown in the textview – Gusinator Jun 10 '15 at 21:03
  • You will NOT return a string from onPostExecute to onCreate. Instead you will set that string in onPostExecute to your textview. – greenapps Jun 10 '15 at 21:04
  • @greenapps Is it possible to set a textview from a different class? – Gusinator Jun 10 '15 at 21:08
  • Yes. But it is easier if your AsyncTask is an inner class of your Activity. – greenapps Jun 10 '15 at 21:11
  • @greenapps I'm trying to keep a clean design pattern which is im trying to do stuff in different classes – Gusinator Jun 10 '15 at 21:14
  • 1
    There is nothing dirty in putting that little task in your activity. And for the moment you should be more concerned to get this running i think. – greenapps Jun 10 '15 at 21:16
  • @greenapps True, I've removed the method calling and i am just using execute() but still when debugging its failing at the BufferReader line giving the same exception – Gusinator Jun 10 '15 at 21:18
  • Please update your code here. Also show your onPostExecute(). – greenapps Jun 10 '15 at 21:21
  • 'return "nothing". Better: return ex.getMessage(); As you will display result in a textview and so the user will see it. – greenapps Jun 10 '15 at 21:23
  • @greenapps I don't have a onPostExecute(); I honestly don't have a clue how i would implement it with my code – Gusinator Jun 10 '15 at 21:32
  • If you just would google for asynctask example you would see how to add an onPostExecute to your AsyncTask. – greenapps Jun 10 '15 at 21:34
  • @greenapps It's not clear how i am suppose to retrieve the string from the method and display in the textview – Gusinator Jun 10 '15 at 21:36
  • What is not clear? Adapt your code here and show what you tried. – greenapps Jun 10 '15 at 21:37
  • The string is the String parameter of onPostExecute. And that is the same string as returned by doInBackground. That is how it works. – greenapps Jun 10 '15 at 21:38
  • @greenapps i've updated what I have tried so far, i've tried returning a StringBuilder in the doInBackground then used StringBuilder in the param of the onPostExecute to return a string but it doesn't work – Gusinator Jun 10 '15 at 21:45
  • You are returning a String in doInBackground and that is ok. But you did not change as i already asked before. And you have no code in onPostExecute. I told you already which code you should put there. Also place a log statement in it so you know it is called. – greenapps Jun 10 '15 at 21:57
  • And and and.. you still have wrong code in onCreate!!!! – greenapps Jun 10 '15 at 21:59
  • 'return null'. Do not do that. I also told you already what you had to put there before. Do as i suggest please as this story will never have an end... – greenapps Jun 10 '15 at 22:00
  • @greenapps The code in the onCreate is correct though right? How else am i suppose to execute the method? – Gusinator Jun 10 '15 at 22:18
  • @Gusinator please check my answer edit.. – n1nsa1d00 Jun 10 '15 at 22:24
  • No it is not correct. And i already told you which lines you had to remove. Why do i have to repeat that? – greenapps Jun 10 '15 at 22:28

2 Answers2

0

Direct Reason for the Exception is that you shouldn't run Networking on your main thread, instead, run it in a background thread and only update your UI from it.

One way to do that is AsyncTask (as you are trying), another way is to use a library such as Volley or retrofit which take care of the background threading for you.

TommySM
  • 3,793
  • 3
  • 24
  • 36
  • But how do I return the string from the URL to present to the UI? – Gusinator Jun 10 '15 at 20:59
  • [This SO Answer](http://stackoverflow.com/questions/28172496/android-volley-how-to-isolate-requests-in-another-class/30604191#30604191) can help you understand, I truly suggest to go through the links I posted in the answer, also, mind what @greenapps mentioned. – TommySM Jun 10 '15 at 21:03
0

You should not directly invoke the doInBackground method of AsyncTask instead you should call execute method on your AsyncTask object which will take care executing the network request in the background thread. developer.android.com/reference/android/os/AsyncTask.html

siva
  • 1,850
  • 13
  • 14