Android 无限循环中的服务
我想调用一个服务,该服务重复查询Parse.com数据库并监视特定属性。以下是我目前得到的结果:Android 无限循环中的服务,android,android-service,parse-platform,Android,Android Service,Parse Platform,我想调用一个服务,该服务重复查询Parse.com数据库并监视特定属性。以下是我目前得到的结果: public class Battle extends Service { @Override public int onStartCommand(Intent intent,int flags,int startId) { Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); ParseUser c
public class Battle extends Service {
@Override
public int onStartCommand(Intent intent,int flags,int startId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
ParseUser currentUser = ParseUser.getCurrentUser();
username = currentUser.getString("username");
findinBackground();
return START_STICKY;
}
private void findinBackground(){
//public void run() {
// TODO Auto-generated method stub
while(true)
{
query = ParseUser.getQuery();
query.whereEqualTo("isAttacking", username);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> objects, ParseException e) {
if ((e == null)&(objects.size() != 0))
{
// The query was successful.
ParseUser attacker = objects.get(0);
String attackerName = attacker.getUsername();
Log.i("ambustest",attackerName);
makeToast(attackerName);
}
else
{
Log.i("fd","Something went wrong.");
}
}
});
}
}
}
公共类战斗扩展服务{
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId)
{
Toast.makeText(此“服务已启动”,Toast.LENGTH_LONG).show();
ParseUser currentUser=ParseUser.getCurrentUser();
username=currentUser.getString(“用户名”);
findinBackground();
返回开始时间;
}
私有void findinBackground(){
//公开募捐{
//TODO自动生成的方法存根
while(true)
{
query=ParseUser.getQuery();
查询。whereEqualTo(“isAttacking”,用户名);
findInBackground(新的FindCallback(){
公共void done(列出对象,parsee异常){
如果((e==null)和(objects.size()!=0))
{
//查询成功。
ParseUser攻击者=objects.get(0);
字符串attackerName=attacker.getUsername();
Log.i(“ambustest”,附件名称);
makeToast(attackerName);
}
其他的
{
Log.i(“fd”,“出了点问题。”);
}
}
});
}
}
}
此代码编译良好,但在运行时停止响应。以下是我的日志:
服务与UI在同一线程上运行。如果要执行耗时的操作,需要在单独的线程中启动它们。您需要在单独的线程上调用服务
@Override
public int onStartCommand(Intent intent,int flags,int startId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
ParseUser currentUser = ParseUser.getCurrentUser();
username = currentUser.getString("username");
new Thread()
{
public void run() {
findinBackground();
}
}.start();
return START_STICKY;
}
需要注意的是,Intent服务是在单独的线程上自动调用的,而常规服务则不是。最好的解决方案是远程服务,该服务带有一个处理程序,可以报告您的客户端(活动)的更改 您的服务将在一个单独的进程中运行 首先,您需要一个AIDL-作为与服务和客户机通信的接口
// IRemoteService.aidl
package de.contecon.android.util.abstractservice;
interface IRemoteService {
void registerCallback(IRemoteServiceCallback mCallback);
void unregisterCallback(IRemoteServiceCallback mCallback);
}
您的服务可以是这样的
//RemoteService.java
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY_COMPATIBILITY;
}
@Override
public void onCreate() {
// While this service is running, it will continually increment a
// number. Send the first message that is used to perform the
// increment.
mHandler.sendEmptyMessage(REPORT_MSG);
}
@Override
public IBinder onBind(Intent intent) {
// Select the interface to return. If your service only implements
// a single interface, you can just return it here without checking
// the Intent.
if (IRemoteService.class.getName().equals(intent.getAction())) {
return mBinder;
}
//Example for a second Binder
// if (IRemoteServiceSecondary.class.getName().equals(intent.getAction())) {
// return mBinderSec;
// }
return null;
}
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public void registerCallback(IRemoteServiceCallback mCallback) throws RemoteException {
if (mCallback != null) mCallbacks.register(mCallback);
}
@Override
public void unregisterCallback(IRemoteServiceCallback mCallback) throws RemoteException {
if (mCallback != null) mCallbacks.unregister(mCallback);
}
};
/**
* Our Handler used to execute operations on the main thread. This is used
* to schedule increments of our value.
*/
private final Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
// It is time to bump the value!
case REPORT_MSG: {
// Up it goes.
int value = ++mValue;
// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
for (int i=0; i<N; i++) {
try {
mCallbacks.getBroadcastItem(i).valueChanged(value);
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mCallbacks.finishBroadcast();
// Repeat every 1 second.
sendMessageDelayed(obtainMessage(REPORT_MSG), 1*1000);
} break;
default:
super.handleMessage(msg);
}
}
};
AndroidManifest.xml
<service
android:name=".service.RemoteService"
android:process=":remote"
android:enabled="true" >
<intent-filter>
<!-- These are the interfaces supported by the service, which
you can bind to. -->
<action android:name="de.your.path.util.abstractservice.IRemoteService" />
<!-- This is an action code you can use to select the service
without explicitly supplying the implementation class. -->
<action android:name="your.action.uri.code.REMOTE_SERVICE" />
</intent-filter>
</service>
<service
android:name=".service.RemoteService"
android:process=":remote"
android:enabled="true" >
<intent-filter>
<!-- These are the interfaces supported by the service, which
you can bind to. -->
<action android:name="de.your.path.util.abstractservice.IRemoteService" />
<!-- This is an action code you can use to select the service
without explicitly supplying the implementation class. -->
<action android:name="your.action.uri.code.REMOTE_SERVICE" />
</intent-filter>
</service>