Issue
I have created a nested class that extends the AsyncTask to extract data from a database. When the extraction is completed, it sets a global variable ("notificationsExtracted") to true, to say that the process is complete.
In the main calling code, I set up a while loop that waits for that global variable to become true, before using the data that was extracted, i.e.
while(!notificationsExtracted) {}
...now continue running other code...
On all phones except one, this works perfectly, but the one phone (Conexis x2 - Android 7.0) refuses to reflect the global variable being set to true.
When I do logging, it shows the flow of code instantiating the class, pulling the data works, setting the global variable to true, and then nothing. On other phones, it does the above, but then continues running further code in the main program.
Briefly, I have the following in the calling program
public class FragmentMain extends Fragment {
static private Boolean notificationsExtracted;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main_layout, parent, false);
...
Log.i("notif", "1");
notificationsExtracted = false;
GetNotificationsNewMySQL getNotificationsNewMySQL = new GetNotificationsNewMySQL();
getNotificationsNewMySQL.execute("");
while (!notificationsExtracted) { };
Log.i("notif", "2");
...
and then the nested class
private class GetNotificationsNewMySQL extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user, pass);
Statement st = con.createStatement();
String q = "SELECT COUNT(*) AS cnt FROM training.app_notifications";
Log.i("notif", "a");
ResultSet rs = st.executeQuery(q);
Log.i("notif", "b");
ResultSetMetaData rsmd = rs.getMetaData();
Log.i("notif", "c");
while (rs.next()) {
notificationCount = Integer.parseInt(rs.getString(1).toString());
}
Log.i("notif", "d");
notificationsExtracted = true;
} catch (Exception e) {
Log.i("notif", "error extracting");
e.printStackTrace();
}
if (notificationsExtracted)
Log.i("notif", "true");
else
Log.i("notif", "false");
return "";
}
@Override
protected void onPostExecute(String result) {
}
}
Now on all phones except the one phone, it logs the following sequence of program flow
2019-11-15 11:18:40.338 1951-1951/com.example.pdcapp I/Notif: 1
2019-11-15 11:18:40.339 1951-1951/com.example.pdcapp I/Notif: 2
2019-11-15 11:18:40.438 1951-1951/com.example.pdcapp I/notif: 1
2019-11-15 11:18:40.512 1951-2025/com.example.pdcapp I/notif: a
2019-11-15 11:18:40.521 1951-2025/com.example.pdcapp I/notif: b
2019-11-15 11:18:40.521 1951-2025/com.example.pdcapp I/notif: c
2019-11-15 11:18:40.522 1951-2025/com.example.pdcapp I/notif: d
2019-11-15 11:18:40.522 1951-2025/com.example.pdcapp I/notif: true
2019-11-15 11:18:40.522 1951-1951/com.example.pdcapp I/notif: 2
except the one phone I get the following, with the result that the phone hangs, i.e. it never gets past the while loop:
2019-11-15 11:20:57.153 20089-20089/com.example.pdcapp I/Notif: 1
2019-11-15 11:20:57.154 20089-20089/com.example.pdcapp I/Notif: 2
2019-11-15 11:20:57.196 20089-20089/com.example.pdcapp I/notif: 1
2019-11-15 11:20:57.267 20089-20348/com.example.pdcapp I/notif: a
2019-11-15 11:20:57.274 20089-20348/com.example.pdcapp I/notif: b
2019-11-15 11:20:57.274 20089-20348/com.example.pdcapp I/notif: c
2019-11-15 11:20:57.274 20089-20348/com.example.pdcapp I/notif: d
2019-11-15 11:20:57.274 20089-20348/com.example.pdcapp I/notif: true
I would appreciate help on this please. As reference, I previously loooked for help on the following link https://androidforums.com/threads/while-loop-not-exiting.1315976/
Solution
What you are doing goes against the principal of asynchronous execution. If you start an asynchTask, but then wait until it's finsished, it's not really async.
This is ok though, sometimes you simply need things to be done in a certain order but you can't do it on the main-thread.
I'm not exactly sure why your program doesn't work on a technical level, but I think I had a similar problem once. I believe that in Java, updating a variable from within one thread does not necessarily update the variable for all other threads too. Does Android Studio give you a warning on the while-loop?
I hope someone who has more experience with multi-threading in Java can say something about this.
However, the solution to your Problem is easy:
You want whatever Code after the while-loop to execute after the AsyncTask finished excecuting, so simply excecute that Code in the onPostExcecute
method.
Answered By - Destinator
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.