2013-11-11 3 views
0

Я хочу, чтобы вызвать службу, которая неоднократно запрашивает базу данных Parse.com и контролирует конкретный attribute.Here то, что Ive получил до сих пор:службы в бесконечной андроида петли

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."); 
      } 
      } 
     }); 
    } 
} 

} 

Этот код компилируется нормально, но перестает отвечать на запросы runtime.Here мой logcat: Logcat

ответ

1

Вам необходимо позвонить в службу в отдельном потоке

@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; 
} 

Следует отметить, что Намерение служба автоматически вызывается в отдельном потоке, однако регулярное обслуживание нет.

0

Услуги выполняются в той же теме, что и ваш пользовательский интерфейс. Если вы хотите выполнять трудоемкие операции, вам нужно спустить их в отдельный поток.

0

Лучшим решением является удаленная служба с обработчиком, который сообщает вашим клиенту (специалистам) об изменениях.

http://developer.android.com/reference/android/app/Service.html

Сервис-центр будет работать в отдельном процессе

Прежде всего, необходимо 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); 
      } 
     } 
    }; 

И ваш клиент

/** 
    * This implementation is used to receive callbacks from the remote 
    * service. 
    */ 
    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() { 
     /** 
     * This is called by the remote service regularly to tell us about 
     * new values. Note that IPC calls are dispatched through a thread 
     * pool running in each process, so the code executing here will 
     * NOT be running in our main thread like most other things -- so, 
     * to update the UI, we need to use a Handler to hop over there. 
     */ 
     public void valueChanged(int value) { 
      mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0)); 
     } 
    }; 
    private static final int BUMP_MSG = 1; 
    private Handler mHandler = new Handler() { 
     @Override public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case BUMP_MSG: 
        mCallbackText.setText("Received from service: " + msg.arg1); 
        break; 
       default: 
        super.handleMessage(msg); 
      } 
     } 
    }; 

public void startService() { 
     // Make sure the service is started. It will continue running 
     // until someone calls stopService(). 
     // We use an action code here, instead of explictly supplying 
     // the component name, so that other packages can replace 
     // the service. 
     startService(new Intent(
       "your.action.uri.code.REMOTE_SERVICE")); 

    } 

    public void stopService() { 
     // Cancel a previous call to startService(). Note that the 
     // service will not actually stop at this point if there are 
     // still bound clients. 
     stopService(new Intent(
       "your.action.uri.code.REMOTE_SERVICE")); 
    } 

/** 
    * Class for interacting with the main interface of the service. 
    */ 
    private ServiceConnection mConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, 
             IBinder service) { 
      // This is called when the connection with the service has been 
      // established, giving us the service object we can use to 
      // interact with the service. We are communicating with our 
      // service through an IDL interface, so get a client-side 
      // representation of that from the raw service object. 
      mService = IRemoteService.Stub.asInterface(service); 
      mCallbackText.setText("Attached."); 
      // We want to monitor the service for as long as we are 
      // connected to it. 
      try { 
       mService.registerCallback(mCallback); 
      } catch (RemoteException e) { 
       // In this case the service has crashed before we could even 
       // do anything with it; we can count on soon being 
       // disconnected (and then reconnected if it can be restarted) 
       // so there is no need to do anything here. 
      } 
      // As part of the sample, tell the user what happened. 
      Toast.makeText(RemoteServiceBinding.this, "service connected", 
        Toast.LENGTH_SHORT).show(); 
     } 
     public void onServiceDisconnected(ComponentName className) { 
      // This is called when the connection with the service has been 
      // unexpectedly disconnected -- that is, its process crashed. 
      mService = null; 
      mCallbackText.setText("Disconnected."); 
      // As part of the sample, tell the user what happened. 
      Toast.makeText(RemoteServiceBinding.this,"service disconnected", 
        Toast.LENGTH_SHORT).show(); 
     } 
    }; 

private void bindService(){ 
     // Establish a couple connections with the service, binding 
     // by interface names. This allows other applications to be 
     // installed that replace the remote service by implementing 
     // the same interface. 
     bindService(new Intent(IRemoteService.class.getName()), 
       mConnection, Context.BIND_AUTO_CREATE); 
     bindService(new Intent(IRemoteServiceSecondary.class.getName()), 
       mSecondaryConnection, Context.BIND_AUTO_CREATE); 
     mIsBound = true; 
     mCallbackText.setText("RemoteServiceBinding."); 
    } 

    private void unbindService(){ 
     if (mIsBound) { 
      // If we have received the service, and hence registered with 
      // it, then now is the time to unregister. 
      if (mService != null) { 
       try { 
        mService.unregisterCallback(mCallback); 
       } catch (RemoteException e) { 
        // There is nothing special we need to do if the service 
        // has crashed. 
       } 
      } 
      // Detach our existing connection. 
      unbindService(mConnection); 
      unbindService(mSecondaryConnection); 
      mIsBound = false; 
      mCallbackText.setText("Unbinding."); 
     } 
    } 

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> 
Смежные вопросы