我正在编写一个应用程序,应该每隔15分钟从一个网站获取数据(在代码中只需10秒钟来检查它是否可以轻松工作)。我在其中使用服务和处理程序。以下是我的服务类:
应该每隔10秒调用一次getRating(),我使用ION库在其中进行计算,然后调用getData方法。问题是调用方法getRating之后的代码是在方法完成之前执行的(我尝试在方法内部和之后显示toast,后面的那个显示第一个)因此变量y没有正确更新。
我的问题是为什么会发生这种情况?我应该怎么做才能纠正它? 我在想什么:
谢谢。
package com.example.l50.bla;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.NotificationCompat;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
public class MyService extends Service {
Handler mHandler;
int T;
void getData(int x)
{
T=x;
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onCreate() {
mHandler = new Handler();
Runnable r = new Runnable() {
@Override
public void run() {
getRating();
int y=T;
mHandler.postDelayed(this, 10000);
}
};
mHandler.postDelayed(r, 10000);
}
void getRating() {
String url ="http://www.somewebsite.com";
Ion.with(getApplicationContext())
.load(url)
.asString()
.setCallback(new FutureCallback<String>() {
@Override
public void onCompleted(Exception e, String result) {
int x;
// do some calculations, the result of these calculations is stored in x
getData(x);
});
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Search Stopped", Toast.LENGTH_LONG).show();
}
}
UPD :在我的情况下,我可以保证x的值不会为零,所以我可以在x尚未更新时跳过,这样可以解决问题,但有一些延迟。我怎样才能更有效率地做到这一点?
答案 0 :(得分:0)
这里有一些问题:
Handler
中创建Service
与在应用主线程中的后台线程中运行不同。Runnable
正在重新排队,所以只要系统不处于低功耗模式,它就会继续执行。一旦发生这种情况,您的Service
将不再获得执行上下文,并且您的轮询将无效。考虑使用JobScheduler
(需要API 21或更新版本)或警报来处理定期请求。Runnable
后getRating()
代码运行的原因是因为getRating()
调用的ION方法是异步。它将在后台线程上正常运行,然后在完成后通过提供的方法回调您的应用程序。如果你在getData()
方法中做了类似的事情,那么你可能会遇到类似的问题。