我是新来的,目前我正在做正在处理背景和检查手机中的流程的应用,如果"com.igg.castleclash"
正在进程中列表它将castleclash值设置为true并在Firebase中保存数据。一切正常,但我无法使用addValueEventListener
从Firebase读取数据。
public class SensorService extends Service {
boolean castleclash = false;
DatabaseReference databaaseUsers;
public SensorService(Context applicationContext) {
super();
}
public SensorService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
databaaseUsers.child("user1").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UsersData user = dataSnapshot.getValue(UsersData.class);
Log.i("user name", user.getName());
}
@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("Failed to read value.", error.toException());
}
});
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Intent broadcastIntent = new
Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
}
public void startTimer() {
synchronized (this) {
while (true) {
try {
wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
databaaseUsers = FirebaseDatabase.getInstance().getReference();
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
final List<ActivityManager.RunningAppProcessInfo> runningProcesses = manager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo process : runningProcesses) {
if (process.processName.equals("com.igg.castleclash")) {
castleclash = true;
break;
} else {
castleclash = false;
}
}
UsersData user1 = new UsersData(castleclash, "name");
databaaseUsers.child("user1").setValue(user1);
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
为什么这不起作用?
答案 0 :(得分:3)
有很多问题。最重要的是,您认为此处理不“在后台”发生。它在主线程上运行。这是与documentation:
中描述的服务的常见误解什么是服务?
关于Service类的大多数混淆实际上围绕着什么 它不:
- 服务不是一个单独的过程。 Service对象本身并不意味着它在自己的进程中运行;除非另有 指定,它在与它所属的应用程序相同的进程中运行 的。
- 服务不是线程。它不是从主线程开始工作的手段(以避免应用程序无响应错误)。
IntentService是一个方便的服务子类,用于完成主线程的工作。
while(true)
中的startTimer()
循环无休止地运行。 addValueEventListener()
中对onStartCommend()
的调用永远不会执行,因为startTimer()
永远不会返回。
数据库更改侦听器在主线程上运行。因为主线程被wait()
的调用阻止,所以onDataChange()
回调将无法运行(如果成功添加了侦听器)。
另外,要查看您对startTimer()
中的数据库的写入是否失败,请添加CompletionListener
。失败的最常见原因是由不正确的安全规则导致的权限被拒绝。
UsersData user1 = new UsersData(castleclash, "name");
databaaseUsers.child("user1").setValue(user1, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError == null) {
Log.d(TAG, "onComplete: success");
} else {
Log.e(TAG, "onComplete: failed", databaseError.toException());
}
}
});
答案 1 :(得分:1)
你看过David East的这段视频吗? https://youtu.be/lpFDFK44pX8 我遵循他的方法,它有很多帮助。
第一行,你应该这样写,
DatabaseReference dbRef = FirebaseDatabase.getInstance()。getReference
然后,您需要为控制台中的每个数据库声明另一个DatabaseReference。
DatabaseReference moooww = dbRef.child(“nameOfYourDbValue”);
视频中显示的其余部分。