lundi 26 mai 2014

Java - Android : Thread being called (run) twice


Vote count:

0




I would like some help regarding Java - Android MultiThreading


While learning to develop my app in a multi-threading way in order to take advantage of the ever-growing multi-core devices market share (most devices are quad core now, some even octo-core), I ran in a situation where my threads are either being calling twice or running twice.


I just don't why and how.


I am implementing last Facebook SDK and I am using it to fetch the end-user friends list, which seems to do the work. Since I am running this operation in an AsyncTask, I am not using request.executeAsync(). Instead I am using request.executeAndWait(). Facebook JavaDoc does state that this method must only be used if I am not in a the Main UI Thread which is my case otherwise I would get a NetworkOnMainThreadException.


Anyway, this is where the weird behavior is happening.



private final ArrayList<GraphUser> userFriendsList = new ArrayList<GraphUser>();
public final void fetchFriendsList() {
if (this.session != null && this.session.isOpened()) {
final Request requestUserFriendsList = Request.newMyFriendsRequest(
this.session, new Request.GraphUserListCallback()
public final void onCompleted(final List<GraphUser> users, final Response response) {
if (users != null && users.size() > 0) {
Log.v("Retrieved Friends List -> ", String.valueOf(users.size()));
userFriendsList.addAll(users);
}
}
}
);
if (this.asyncFlag)
requestUserFriendsList.executeAsync();
else
requestUserFriendsList.executeAndWait();
}
}


In my case, asyncFlag is set to false because I need to do stuff synchronously in that specific order :



  1. Fetch User Friends List (not on the Main (UI) Thread)

  2. Save friends list on device (separate new thread)

  3. Save friends list on a server (separate new thread)


Following this pattern, the line userFriendsList.addAll(users); is called twice. In the logcat, the Log.vis showed twice as well, and finally looking with the debugger, the content of the user friends list is made of duplicates.


But that's not all ... step 2 and 3 are indeed two separate threads which are both created and spawned within the same method : public final void asyncSaveFacebookFriendsList().


And guess what, this method is even called twice !


just why ?


At the beginning I was calling the method for step 2 and 3 like this :



[...]
userFriendsList.addAll(users);
asyncSaveFacebookFriendsList(); // it was private before
[...]


This is where the issue started as both line were running twice.


So I thought, alright, I'll call it later like this :



[...]
fetchFriendsList();
asyncSaveFacebookFriendsList(); // it is now public
[...]


But the issue remains still. I I don't call public final void asyncSaveFacebookFriendsList(), then nothing is run twice.


Why does this issue happen ? Is there something I did not get in Java Threads ?


I do not think this is somehow related to the Facebook SDK because following the same pattern (and doing it also at the same time), I have the same issues when fetching and storing the end-user Twitter friends list.


So I do believe I am doing something wrong. Does someone have any idea in what possible case a thread is called twice ?


Note : all threads are started this way : thread.start(). I am not using any ThreadPool nor the ExecutorService.


In case you need more background context : Content of AsyncTask : (no need to wonder why Void and Long, I remove the irrelevant code related to it)



private final class FetchFriendsLists extends AsyncTask<Long, Integer, Void> {
protected final Void doInBackground(final Long... params) {
if (params[0] != Long.valueOf(-1)) {
[...]
twitterAPI.fetchUserFriendsList();
publishProgress(1, -1);
}
if (params[1] == Long.valueOf(0)) {
[...]
facebookAPI.fetchFriendsList();
publishProgress(-1, 0);
}
return null;
}

protected final void onProgressUpdate(Integer... flags) {
super.onProgressUpdate(flags);
if (flags[0] != -1)
twitterAPI.asyncSaveFacebookFriendsList();
if (flags[1] == 0)
facebookAPI.asyncSaveFacebookFriendsList();
}
}


asked 1 min ago






Aucun commentaire:

Enregistrer un commentaire