如何创建Async Task RecyclerView Fragment Java

时间:2017-06-28 17:22:47

标签: java android android-fragments asynchronous android-recyclerview

LocationFragment类:

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类:

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界面:

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

JSONAsyncTask类:

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;
    }

}

我试图在片段中创建异步任务。我这样做的方式适用于我的RSS阅读器,但不知怎的,它对我的​​JSONParser不起作用。我几乎尝试了这个主题的每个答案How to fix android.os.NetworkOnMainThreadException?

这些选项都没有解决我的问题:

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)

我知道这与Async任务有关,但我不知道我做错了什么

1 个答案:

答案 0 :(得分:1)

sendRequest()函数必须在后台发生(也就是asynctask中的doinbackground)

所有这些都是因为你需要在反向线程上进行网络调用,

话虽如此,您可以使用Volley或Retrofit Libraries来简化网络电话

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

改造 - http://square.github.io/retrofit/

编辑:

这是你的成功:

 @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);

您现在正在使用mainthread(这就是为什么您可以更改视图并执行findviewbyid等等...)

比你尝试

 locationData = json.storeJSONData();

再次调用sendrequest,这次是在mainthread上,就像Slevin试图暗示的那样,这将解决当前的崩溃问题。