我是Java的新手,并尝试制作一个定期从我的Ubidots变量中读取一些信息的Android APP。
经过网上的一些研究后,我设法找到了这种做法..
问题是它只执行一次。在第一次迭代之后,它再也不会再通过syncTimer了。
Runnable syncTimer = new Runnable() {
public void run() {
ubi.execute(0);
if (!syncComplete)
{
System.out.println("Sync not completed. We'll wait");
while (!syncComplete)
{
//wait.
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
try
{
syncComplete(tempValue, g_tempVal.toString());
}
catch (Exception e)
{
System.err.println("error in executing. It will no longer be run!");
e.printStackTrace();
throw new RuntimeException(e);
}
}
});
}
};
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(syncTimer, 0, 2, TimeUnit.SECONDS);
这是我的代码,对此问题的任何帮助?我想知道在Google上搜索什么以找到解决问题的方法。
我从未用Java / Android编程,只使用过其他语言。
syncComplete是AsyncTask之后的布尔集,它连接到Ubidots并检索变量。
public class ApiUbidots extends AsyncTask<Integer, Void, Void> {
private final String API_KEY = "key";
private final String VARIABLE_ID = "var";
@Override
protected Void doInBackground(Integer... params) {
ApiClient apiClient = new ApiClient(API_KEY);
Variable temperature = apiClient.getVariable(VARIABLE_ID);
if (params[0] == 0)
{
g_tempVal = temperature.getValues()[0].getValue();
syncComplete = true;
}
if (params[0] == 1)
{
//implement write function
}
return null;
}
}
答案 0 :(得分:0)
如果您的帖子由其他帖子制作,则syncComplete
的更改不可见。您需要将syncComplete
变量声明为volatile,如下所示:
public volatile boolean syncComplete=false;
使用volatile变量可以降低内存一致性错误的风险,因为对volatile变量的任何写入都会建立与之后读取同一变量的先发生关系。这意味着对volatile变量的更改始终对其他线程可见。
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
此外,通过在while循环中旋转来主动等待是不好的做法。请尝试锁定。