我创建了一个嵌套类,该类扩展AsyncTask以从数据库中提取数据。提取完成后,它将全局变量("notificationsExtracted"(设置为true,表示过程已完成。
在主调用代码中,我设置了一个while循环,等待全局变量变为true,然后再使用提取的数据,即
while(!notificationsExtracted) {}
...now continue running other code...
在除一部手机外的所有手机上,这都非常有效,但只有一部手机(Conexis x2-Android 7.0(拒绝反映设置为true的全局变量。
当我进行日志记录时,它显示了实例化类、提取数据工作、将全局变量设置为true,然后什么都不显示的代码流。在其他手机上,它会执行上述操作,但随后会继续在主程序中运行进一步的代码。
简而言之,我在调用程序中有以下内容
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");
...
然后是嵌套类
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) {
}
}
现在,在除一部手机外的所有手机上,它记录以下程序流序列
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
除了我得到的一部手机,结果是手机挂起,也就是说,它永远不会通过while循环:
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
请帮我一下,我将不胜感激。作为参考,我之前在以下链接上寻求帮助https://androidforums.com/threads/while-loop-not-exiting.1315976/
您所做的违背了异步执行的原则。如果你启动了一个asynchTask,但等到它完成后,它就不是真正的异步
不过这没关系,有时你只需要按照特定的顺序来完成事情,但你不能在主线程上完成。
我不太清楚为什么你的程序在技术层面上不起作用,但我想我曾经遇到过类似的问题。我相信,在Java中,从一个线程内更新变量并不一定会更新所有其他线程的变量。安卓工作室会在while循环中给你一个警告吗
我希望对Java中的多线程有更多经验的人能对此有所了解。
然而,问题的解决方案很简单:
您希望while循环之后的任何代码在AsyncTask完成超越后执行,所以只需在onPostExcecute
方法中超越该代码即可。
您能在获得String q、ResultSet和ResultSetMetaData的行之后添加记录器吗?也许它卡在了这些线条上。