-1

LocationFragment class:

public class LocationFragment extends Fragment {
        FragmentNameFactory nameFactory = new FragmentNameFactory();
        List<LocationData> locationData;
        LocationRecyclerAdapter locationRecyclerAdapter = new LocationRecyclerAdapter(locationData);
        public LocationFragment(){
            //Fragment needs a constructor, can be empty
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
            ((MainActivity) getActivity()).setFragmentName(nameFactory.getNameNL(6));
            final View view = inflater.inflate(R.layout.flocationrecylce, container, false);
            new JSONAsyncTask(new JSONCallBack(){
                //This method updates the UI
                @Override
                public void success(JSONParser jsonParser) {
                    final JSONParser json = jsonParser;
                    //This part makes sure it is able to multi thread.
                    //In case this method is missing the application will crash upon refreshing this fragment

                            locationData = json.storeJSONData();
                            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.locationRecyclerView);
                            recyclerView.setHasFixedSize(true);
                            recyclerView.setAdapter(locationRecyclerAdapter);
                            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
                            recyclerView.setLayoutManager(linearLayoutManager);

                }
                //In case of failure the method sprints the log to the debugging console
                @Override
                public void failed() {
                    System.out.print("Failure");
                }
                //Sends the task to the doInBackground method inside RSSReaderAsync, which execute the code inside RSSReader
            }).execute("");

            return view;
        }
        @Override
        public void onViewCreated(View view, Bundle savedInstance){
            super.onViewCreated(view, savedInstance);

        }
        @Override
        public void onActivityCreated(Bundle savedInstance){
            super.onActivityCreated(savedInstance);
        }
    }

JSONParser class:

public class JSONParser {
    String url;
    String requestMethod;
    List<LocationData> locations;
    public JSONParser(String url, String requestMethod){
        this.url = url;
        this.requestMethod = requestMethod;
        locations = storeJSONData();
    }


    private String read(BufferedReader bufferedReader) throws IOException {
        //Creates new StringBuilder to avoid escaping chars

        StringBuilder stringBuilder = new StringBuilder();
        //Creates new variable

        String currentLine;
        //Gets the currentLine

        while((currentLine = bufferedReader.readLine()) !=null ){

            //Adds the currentLine to the stringBuild if the currentLine is not null

            stringBuilder.append(currentLine);
        }
        //Returns the StringBuilder is String format

        return stringBuilder.toString();
    }

    public JSONObject sendRequest() throws IOException, JSONException {
        //Get the URL from the constructor

        URL url = new URL(this.url);
        //Opens the connection

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //Sets the requestMethod

        connection.setRequestMethod(this.requestMethod);
        //Sets the requestProperties

        connection.setRequestProperty("Content-type", "application/JSON");
        //Tries to read the through the BufferedReader

        try {
            //Creates new BufferedReader & InputStreamReader which get the input of the connection

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            //Stores the output of the connection in a string

            String jsonText = read(bufferedReader);
            //Creates a new JSON object from the above String

            JSONObject json = new JSONObject(jsonText);
            //Returns the JSON Object

            return json;
        } finally {
            //Disconnects from the URL
            connection.disconnect();
        }
    }

    public List<LocationData> storeJSONData(){
        //Creates temporary List

        List<LocationData> tempList = new ArrayList<>();
        try{
            //Sends request

            JSONObject json = sendRequest();
            //For loop to parse all the data from the request

            for(Integer i =0; i < json.getJSONArray("response").length(); i++){
                tempList.add(new LocationData(json.getJSONArray("response").getJSONObject(i).getString("name"),
                                              json.getJSONArray("response").getJSONObject(i).getString("zipcode"),
                                              json.getJSONArray("response").getJSONObject(i).getString("street"),
                                              json.getJSONArray("response").getJSONObject(i).getString("streetnumber"),
                                              json.getJSONArray("response").getJSONObject(i).getDouble("longitude"),
                                              json.getJSONArray("response").getJSONObject(i).getDouble("latitude"),
                                              json.getJSONArray("response").getJSONObject(i).getString("city")));
            }
        }
        catch (IOException e){
            System.out.print(e);
        }
        catch (JSONException e){
            System.out.print(e);
        }
        //Returns the list

        return tempList;
    }
}

JSONCallBack interface:

public interface JSONCallBack {
    void success(JSONParser jsonParser);
    void failed();
}

JSONAsyncTask class:

public class JSONAsyncTask extends AsyncTask<String, Integer, Integer> {
    private JSONCallBack jsonCallBack;

    public JSONAsyncTask(JSONCallBack jsonCallBack) {
        this.jsonCallBack = jsonCallBack;
    }

    @Override
    protected Integer doInBackground(String... params) {
        JSONParser parser = new JSONParser("http://grwn.ddns.net:1337/locations", "POST");
        jsonCallBack.success(parser);
        return null;
    }

}

I'm trying to create a Async task inside a Fragment. The way I did this works for my RSS reader but somehow it doesn't work for my JSONParser. I tried almost each answer of this topic How to fix android.os.NetworkOnMainThreadException?

No of those options fix my issue:

android.os.NetworkOnMainThreadException
                                                                                  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
                                                                                  at java.net.SocketInputStream.read(SocketInputStream.java:150)
                                                                                  at java.net.SocketInputStream.read(SocketInputStream.java:120)
                                                                                  at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
                                                                                  at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
                                                                                  at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
                                                                                  at com.android.okhttp.internal.http.HttpConnection.isReadable(HttpConnection.java:155)
                                                                                  at com.android.okhttp.Connection.isReadable(Connection.java:417)
                                                                                  at com.android.okhttp.OkHttpClient$1.isReadable(OkHttpClient.java:93)
                                                                                  at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:339)
                                                                                  at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
                                                                                  at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
                                                                                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
                                                                                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
                                                                                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:243)
                                                                                  at com.example.sande.androidhro.JSONParser.sendRequest(JSONParser.java:69)
                                                                                  at com.example.sande.androidhro.JSONParser.storeJSONData(JSONParser.java:92)
                                                                                  at com.example.sande.androidhro.LocationFragment$1$1.run(LocationFragment.java:46)
                                                                                  at android.os.Handler.handleCallback(Handler.java:751)
                                                                                  at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                  at android.os.Looper.loop(Looper.java:153)
                                                                                  at android.app.ActivityThread.main(ActivityThread.java:6236)
                                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)

I know this has something to do with the Async task but I don't know what I'm doing wrong

Sander bakker
  • 518
  • 1
  • 6
  • 20
  • You again, success is obviously called on ui thread, storeJSONData is using network, storeJSONData is called from success ... The problem is obvious. – Selvin Jun 28 '17 at 17:27
  • @Selvin can you please help me fixing it? I don't know where to start. Posting this kind of comments is not helping – Sander bakker Jun 28 '17 at 17:28
  • Do you understand your code? You have 2 network operations (as rotwang said in previous question: this code is mess) , one you are doing in asynctask and second not... – Selvin Jun 28 '17 at 17:33

1 Answers1

1

The sendRequest() function must happen in the background (aka doinbackground in the asynctask)

All because you need to make network calls on back thread,

Having said that you can use Volley or Retrofit Libraries instead for easier network calls

Volley - https://developer.android.com/training/volley/index.html

Retrofit - http://square.github.io/retrofit/

EDIT :

this is your onsuccess:

 @Override
 public void success(JSONParser jsonParser) {
      final JSONParser json = jsonParser;
      **locationData = json.storeJSONData();**
      RecyclerView recyclerView = (RecyclerView) 
      view.findViewById(R.id.locationRecyclerView);
      recyclerView.setHasFixedSize(true);
      recyclerView.setAdapter(locationRecyclerAdapter);
      LinearLayoutManager linearLayoutManager = new 
      LinearLayoutManager(getActivity());
      recyclerView.setLayoutManager(linearLayoutManager);

You are now on mainthread(that's why you can change views and do findviewbyid and so on ... )

Than you try

 locationData = json.storeJSONData();

Which calls sendrequest again , this time on mainthread , like Slevin tried to imply , this will fix the current crash .

yanivtwin
  • 617
  • 8
  • 32