简体   繁体   中英

Null object reference even after the object has been initialized

I am attempting to try my best at using fragments for this particular project I am trying to create. I am making all network calls inside a fragment class that I have created. When I call the methods that make the connection and I log the results to the console I am getting all the information from the class, but when I try to access the instance outside of the network call I get a null pointer exception. I have been looking at the docs and at other examples, but most of them do things differently from what I need and the docs make no reference to working with okhttp inside fragments.

The code that I am using is this :

public void testAsyncCreate() {

        OkHttpClient client  = new OkHttpClient();


        RequestBody body = RequestBody.create(CREATE_MEDIA_TYPE, "data={\"process\":\"123\", \"phone\":\"111111111\"}");


        Request request = new Request.Builder()
                .url(ALLWAYS_API)
                .post(body)
                .build();

        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // any additional runnable items go in here
                try {


                    String jsonData = response.body().string(); // the exception is caught at this point
                    Log.d("<Mensajes>",jsonData);
                    //extractCreate = parseExtractCreateDetails(jsonData);
                    if(response.isSuccessful()) {
                        extractCreate = parseExtractCreateDetails(jsonData);
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d("<=====>", "check");
                                Log.d(TAG, "Is this even working?");
                                Log.d("The class has been ok",extractCreate.getCreateR().getAccount_id().toString());
                                Log.d("Another check", extractCreate.getStopsR()[1].getAddress());



                            }
                        });
                    }

                    //getStops(jsonData);

                }catch(IOException e) {

                }catch (JSONException e){

                }


            }
        });
    } // end of asyncCreate

Then inside the onCreateView() method:

ExtractCreate extractCreate = new ExtractCreate();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragments_stops_list, container, false);
        ButterKnife.bind(this, view);

        if (savedInstanceState == null) {
              testAsyncCreate();
        }
        Log.d("<extractCreateCheck>", String.valueOf(extractCreate.getCreateR().getAccount_id()));

        return view:
    }

I can´t figure why this is not working when using fragments, the reason I say that is because if I was to put this inside a regular activity and run it I would be able to use the results of extractCreate anywhere else I wanted, but not in here. Are there any steps that I am missing regarding using okhttp calls inside fragments? the docs are not really making any sense to me at the moment. The stacktrace is as follows:

11-23 09:28:55.569 3288-3288/com.example.testC.demotrackertree E/AndroidRuntime: FATAL EXCEPTION: main                                                                                   
        Process: com.example.testC.demotrackertree, PID: 11142
        java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String at com.example.testC.demotrackertree.models.createmodels.CreateResponse.getAccount_id()' on a null object reference
        at com.example.testC.demotrackertree.ui.fragments.StopCreateFragment.onCreateView(StopCreateFragment.java:95)
        at android.app.Fragment.performCreateView(Fragment.java:2353)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:995)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171)
        at android.app.BackStackRecord.run(BackStackRecord.java:816)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1578)
        at android.app.FragmentManagerImpl$1.run(FragmentManager.java:483)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

As one of the guys suggested, I did what I wanted to do inside of the response,

if(response.isSuccessful()) {
                        extractCreate = parseExtractCreateDetails(jsonData);
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
//                                Log.d("<=====>", "check");
//                                Log.d(TAG, "Is this even working?");
//                                Log.d("The class has been ok",extractCreate.getCreateR().getAccount_id().toString());
//                                Log.d("Another check", extractCreate.getStopsR()[1].getAddress());
                                Parcelable[] parcelable = extractCreate.getStopsR();

                                commodities = Arrays.copyOf(parcelable, parcelable.length, Stops[].class);
                                //Log.d("Commodities size check", String.valueOf(commodities.length));


                                StopsAdapter adapter = new StopsAdapter(extractCreate.getStopsR());
                                mRecyclerView.setAdapter(adapter);
                                RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); // sketchy on this part
                                mRecyclerView.setLayoutManager(layoutManager);
                                mRecyclerView.setHasFixedSize(true);
                                Log.d(TAG, "This is being called from the onCreate method");
                                //();



                            }
                        });
                    }

                    //getStops(jsonData);

                }catch(IOException e) {

                }catch (JSONException e){

                }


            }

Now the contents of the view update accordingly as I specified in my adapter(meaning that the adapter is functioning as I intended) but being that the adaptor is not added until the callback finishes the stack trace prints out

11-23 12:05:40.628 7270-7270/com.example.testC.demotrackertree E/RecyclerView: No adapter attached; skipping layout

And not only that, but the saveInstanceState is not preserved when I rotate the screen.

When you execute your AsyncTask, the operation runs on a background thread at the same time as the UI thread. The Log statement is right after the execute statement, so when the Log statement is executed, the AsyncTask has not loaded the information in the variable yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM