ParseQuery NullPointer Exception Paradox

∥☆過路亽.° 提交于 2019-12-23 02:39:17

问题


This is a follow-up to my previous question: Parse RecyclerView Image Query

I am now having a paradoxical nullpointer exception. I am attempting to extract a list from an inner method, in the way outlined below.

public List<ParseObject> objectList;

public List<String> getData(String filter){

    ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
    query.whereEqualTo("category", filter);
    query.findInBackground(new FindCallback<ParseObject>() {

        public void done(List<ParseObject> downloads, com.parse.ParseException e) {
            if (e == null) {
                objectList=downloads;
            } else {
                Log.d("score", "Error: " + e.getMessage());
            }
        }
    });

    int size = objectList.size();

    for (int i = 0; i<size; i++){
        ParseFile file = (ParseFile) objectList.get(i).get("Image");
        urlList.add(file.getUrl());
    }

    return urlList;

}

How do I solve this? What ways exist which are better than what I am using?

EDIT:

Here is what it's doing. At present there are no exceptions, but the recyclerview is not displaying anything.

  @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.activity_events, container, false);
    setList("sport", rootView);
    return rootView;
}

public void set() {

}

public void setList(String filter, View view){
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);
    MyAdapter myAdapter = new MyAdapter(getData(filter));
    recyclerView.setAdapter(myAdapter);
}

EDIT 2: More updated code:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.activity_events, container, false);
    setList("sport", rootView);
    return rootView;
}

public void set() {

}

public void setList(String filter, View view){
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);
    MyAdapter myAdapter = new MyAdapter(getData(filter));
    recyclerView.setAdapter(myAdapter);
}


private List<String> urlList = new ArrayList<>();



public List<ParseObject> objectList = new ArrayList<>();
public int size;

public List<String> getData(String filter){


    ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
    query.whereEqualTo("category", filter);
    query.findInBackground(new FindCallback<ParseObject>() {

        public void done(List<ParseObject> downloads, com.parse.ParseException e) {
            if (e == null) {
                Toast.makeText(getActivity(), "Downloads retrieved", Toast.LENGTH_SHORT).show();
                objectList.addAll(downloads);
            } else {
                Log.d("score", "Error: " + e.getMessage());
            }

            size = objectList.size();
        }
    });



    for (int i = 0; i<size; i++){
        ParseFile file = (ParseFile) objectList.get(i).get("Image");
        urlList.add(file.getUrl());
    }

    return urlList;

}

EDIT 3: Updated, and I have added my adapter code.

    View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.activity_events, container, false);
    new GetUrlListTask(this).execute("sport");
    return rootView;
}

public void set() {

}



private List<String> urlList = new ArrayList<>();



public List<ParseObject> objectList = new ArrayList<>();
public int size;

public List<String> getData(String filter){


    ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
    query.whereEqualTo("category", filter);
    query.findInBackground(new FindCallback<ParseObject>() {

        public void done(List<ParseObject> downloads, com.parse.ParseException e) {
            if (e == null) {
                Toast.makeText(getActivity(), "Downloads retrieved", Toast.LENGTH_SHORT).show();
                objectList.addAll(downloads);
            } else {

            }

            size = objectList.size();
        }
    });



    for (int i = 0; i<size; i++){
        ParseFile file = (ParseFile) objectList.get(i).get("Image");
        urlList.add(file.getUrl());
    }

    return urlList;

}

private class GetUrlListTask extends AsyncTask<String,Void,List<String>>
{
    private WeakReference<Fragment> weakRef;

    public GetUrlListTask(Fragment frag){
        weakRef = new WeakReference< Fragment >(frag);
    }

    @Override
    protected List<String> doInBackground(String... filters) {
        return getData(filters[0]);
    }

    @Override
    protected void onPostExecute(List<String> urlList) {
        Fragment frag = weakRef.get();
        if (frag != null){
            RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.rv);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(linearLayoutManager);
            MyAdapter myAdapter = new MyAdapter(urlList);
            recyclerView.setAdapter(myAdapter);
        }
    }
}

And My adapter:

   List<String> urls;
ViewGroup parent;

public MyAdapter(List<String> urls){
    this.urls=urls;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_entry, parent);
    MyViewHolder myViewHolder = new MyViewHolder(view);
    this.parent=parent;
    return myViewHolder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    Picasso.with(parent.getContext())
            .load(urls.get(position))
            .into(holder.photo);
    Toast.makeText(parent.getContext(), urls.get(position), Toast.LENGTH_LONG).show();
}

@Override
public int getItemCount() {
    return urls.size();
}

public static class MyViewHolder extends RecyclerView.ViewHolder{

    ImageView photo;

    public MyViewHolder(View itemView) {
        super(itemView);
        photo = (ImageView) itemView.findViewById(R.id.listImage);

    }
}

回答1:


So I am assuming that what you want to do is once you get the urlList, you want to update some view. If that's the case then I think what you want to do it run that whole method in a background task rather than just the query like so:

First change your getData() method:

public List<String> getData(String filter){

    ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
    query.whereEqualTo("category", filter);

    objectList = query.find(); //I think you have to surround this by a try catch or have the method throw an exception

    int size = objectList.size();
    for (int i = 0; i<size; i++){
        ParseFile file = (ParseFile) objectList.get(i).get("Image");
        urlList.add(file.getUrl());
   }

    return urlList;
}

Note that since you are doing a network call, the above method now HAS to run from a background thread.

Then you can use something like an AsyncTask to update a view:

private class GetUrlListTask extends AsyncTask<String,Void,List<String>>
{
    private WeakReference<Fragment> weakRef;

    public PhotoTagsFetchTask(Fragment frag){
        weakRef = new WeakReference< Fragment >(frag);
    }

    @Override
    protected Void doInBackground(String... filters) {
        return getData(filters[0]);
    }

    @Override
    protected void onPostExecute(List<String> urlList) {
        Fragment frag = weakRef.get();
        if (frag != null){
            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(linearLayoutManager);
            MyAdapter myAdapter = new MyAdapter(urlList);
            recyclerView.setAdapter(myAdapter);
        }
    }
}

Note that the use of weak reference above is to avoid context leaks (basically avoids unnecessary memory leaks).

You could also do this:

public void getData(String filter){

ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
query.whereEqualTo("category", filter);
query.findInBackground(new FindCallback<ParseObject>() {

    public void done(List<ParseObject> downloads, com.parse.ParseException e) {
        if (e == null) {
            objectList=downloads;
            int size = objectList.size();

            for (int i = 0; i<size; i++){
              ParseFile file = (ParseFile) objectList.get(i).get("Image");
              urlList.add(file.getUrl());
            }

            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(linearLayoutManager);
            MyAdapter myAdapter = new MyAdapter(urlList);
            recyclerView.setAdapter(myAdapter);
        } else {
            Log.d("score", "Error: " + e.getMessage());
        }
    }
});



}



回答2:


Change objectList=downloads to objectList.addAll(downloads) and add objectList = new ArrayList<>() in the first line.

Also move the section starting fromobjectList.size() inside the done method of query callback



来源:https://stackoverflow.com/questions/31840590/parsequery-nullpointer-exception-paradox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!