0

I've been looking for a similar problem to mine in order to find a solution, but I seriously couldn't find anything like that.

I was trying to download from parse an array of posts with an asynctask class, and after it gets the posts, it suppose to set the posts array in my page, and perform the setAdapter function in order to set my new posts array.

the problem is, after I've initialized listView and listAdapter in my home fragment,and then I perform the postArray taking from parse function, after it finishes taking the posts array from parse, it cannot update listAdapter because it says the listAdapter and my listView "haven't initialized yet", even though they have.

p.s. sorry for not posting my code in a convenient way, I don't tend to post my code problems that often.

here's my code:

my home fragment:

public class HomeFragment extends Fragment {
View root;
ArrayList<PostClass> postsArrayList = new ArrayList<>();

static boolean isPostsArrayUpdated = false;

ListAdapter listAdapter;
PullToRefreshListView listView;

public void updatePostsArrayList(ArrayList<PostClass> postsArrayList){
    if(!isPostsArrayUpdated){
        // First time updating posts array list
        listAdapter = new ListAdapter(getActivity(), root);
        listView = (PullToRefreshListView) root.findViewById(R.id.list_container);

        this.postsArrayList = postsArrayList;
        listView.setAdapter(listAdapter);
        isPostsArrayUpdated = true;
        root.findViewById(R.id.homeFragmentLoadingPanel).setVisibility(View.GONE);
    }else{
        // Have updated posts before
        this.postsArrayList = postsArrayList;
        listAdapter.notifyDataSetChanged();
    }
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    root = inflater.inflate(R.layout.fragment_home, container, false);
    listView = (PullToRefreshListView) root.findViewById(R.id.list_container);
    listAdapter = new ListAdapter(getActivity(), root);

    Home_Model.getInstance().setPostsArrayList();

    return root;
}

public class ListAdapter extends BaseAdapter implements View.OnClickListener{//....}

my home model:

public class Home_Model {

Home_Model(){}

static final Home_Model instance = new Home_Model();

public static Home_Model getInstance() {
    return instance;
}

public void setPostsArrayList(){
    new setHomePostsArray().execute();
}

public class setHomePostsArray extends AsyncTask<Void, ArrayList<PostClass>, Void>{

    ArrayList<String> followersList;
    ArrayList<PostClass> postsArrayList;

    @Override
    protected Void doInBackground(Void... params) {

        // Getting posts from parse
        String userName = Parse_model.getInstance().getUserClass().get_userName();
        followersList = Parse_model.getInstance().getFollowersByUserNameToString(userName);
        followersList.add(userName);


        postsArrayList = Parse_model.getInstance().getAllUsersPostsByFollowings(followersList);

        for (PostClass currPost : postsArrayList) {
            for (PostClass currLocalDBPost : LocalDBPostsArray) {
                if (currPost.getObjectID().equals(currLocalDBPost.getObjectID())) {
                    currPost.set_postPicture(currLocalDBPost.get_postPicture());

                }
            }
        }
        //Updating home page
        onProgressUpdate(postsArrayList);


        // Updating local data base in new posts
        //checking in local DB if there are any new posts from parse and update them
        for (PostClass currPost : postsArrayList) {
            boolean isPostExists = false;
            for (PostClass currLocalPost : LocalDBPostsArray) {
                if (currPost.getObjectID().equals(currLocalPost.getObjectID())) {
                    isPostExists = true;
                }
            }
            if (!isPostExists) {
                ModelSql.getInstance().addPost(currPost);
                Log.e("post not exist", "adding local DB");
            }
        }

        //updating followers list in local DB
        Parse_model.getInstance().getUserClass().setFollowersArray(followersList);
        ModelSql.getInstance().updateFollowersArray(currUser);

        return null;
    }

    @Override
    protected void onProgressUpdate(ArrayList<PostClass>... values) {
        //pass the updated postsArrayList to home fragment
        if(setPostsInHomePageDelegate!= null){
            setPostsInHomePageDelegate.setPosts(values[0]);
        }
    }
}


public interface SetPostsInHomePage {
    public void setPosts(ArrayList<PostClass> postsArrayList);
}

SetPostsInHomePage setPostsInHomePageDelegate;

public void setSetPostsInHomePageDelegate(SetPostsInHomePage setPostsInHomePageDelegate) {
    this.setPostsInHomePageDelegate = setPostsInHomePageDelegate;
}

main activity:

public class MainActivity extends Activity {

static HomeFragment homeFragment = new HomeFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

// the home fragment has already been opened during the app opening 

//...

setPostsImHomePage();
 }

//...

public void setPostsImHomePage(){
    Home_Model.getInstance().setSetPostsInHomePageDelegate(new Home_Model.SetPostsInHomePage() {
        @Override
        public void setPosts(ArrayList<PostClass> postsArrayList) {
            homeFragment.updatePostsArrayList(postsArrayList);
        }
    });
}

}

3 Answers 3

1

Try to move your method setPostsImHomePage(...) from MainActivity to HomeFragmentand call it in OnCreateView before return root;.

Sign up to request clarification or add additional context in comments.

4 Comments

thank you for the brilliant idea my friend. I did this exact thing, but unfortunately It gives me a different error exception(which is a progress by its self lol). it says: "android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views." on the listView.setAdapter(listAdapter); line
by the way it seems odd because this post array passing to home fragment is working on the onProgress part in the asyncTask thread, which means it works on the main thread, which there shouldn't be any problem
I cant run the whole downloading posts process on the UI thread, it will slow down the whole app, and also I do run the post array updating to home fragment through the UI thread, because it works through the OnProgressUpdate function of the asyncTask in the home_model class which works on the UI thread..
@Damian Kozlak I have an issue updating ListAdapter to highlight search text here: stackoverflow.com/questions/79041428/…? I would appreciate any insights or ideas you might have on how to fix.
0

Try initializing homeFragment in onCreate before your method call. It's also helpful to know which line(s) are giving you errors.

3 Comments

didn't work. still getting the NullPointerException message.
Which line numbers are throwing the exception?
in my HomeFragment, in updatePostsArrayList function, at first it was throwing an exception at the: listView.setAdapter(listAdapter); but then I tried initializing it again, and then it throws the exception at the listAdapter initializing, and it sayed it didn't even know root(the fragment's view), even though I've initialized it already
0

Obviously your fragment has no View when the result arrives.

You should properly add the fragment to the Activity using the FragmentManager, then in the Fragment's onActivityCreated() callback (which is called by the system after the Fragment has its view properly set), start your AsyncTask.

8 Comments

i'm sorry I totally forgot to mention the home fragment has already been opened during app progress.
If root is null then the View has not yet been created which means either the results arrive too quickly (before the View has a chance to create) or the Fragment is not properly created. Also, you have a memory leak because your model is static and has an indirect reference to your Activity.
I've debugged it and saw the root has been initialized before the posts array import function, and the fragment has created just fine. I've replaced the setPostsImHomePage() function to the onCreate of home fragment as someone else has suggested here.
onCreate() is too soon, you should wait for the view to be created in the fragment first -> Fragment.onActivityCreated() is the best place.
so what should I do exactly? and I'm not so familiar with the onActivityCreated() function, the way it sounds I can only put UI function in it, so where should I place my posts taking thread in?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.