2010-12-21 5 views
2

Я пытаюсь понять, почему мой сервис просачивается из моего приложения.Соединение с Android-сервисом просочилось после начала новой активности

Официальная ошибка, которую я получаю, заключается в том, что Служба не зарегистрирована.

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

Проблема: Когда я возвращаюсь к главному экрану, который дает мне возможность отключить службу, я получаю сообщение об ошибке, которое я изложил ранее, что вызывает исключение IllegalArgumentException (когда я пытаюсь отвязать службу, которая не является зарегистрировано).

Любая помощь была бы принята с благодарностью. Вот код для моего сервиса. Это все, что я включил, потому что это, похоже, проблема, но если вам нужно больше, дайте мне знать.

Заранее спасибо, вот код.

import java.lang.ref.WeakReference; 
import java.util.List; 

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.Binder; 
import android.os.IBinder; 
import android.util.Log; 
import android.widget.Toast; 


public class AccelService extends Service 
{ 
public static boolean listening = false; 
public boolean callMade = false; 
private static Sensor sensor; 
private static SensorManager ASensorManager; 


private SensorEventListener EventListener = 
    new SensorEventListener() { 

    private float x = 0; 
    private float y = 0; 
    private float z = 0; 
    private double max = 0; 
    private double force = 0; 

    public void onAccuracyChanged(Sensor sensor, int accuracy) {} 

    public void onSensorChanged(SensorEvent event) 
    { 

     x = event.values[0]; 
     y = event.values[1]; 
     z = event.values[2]; 
     force = Math.sqrt(x*x+y*y+z*z); 
     Log.i("LocalService", "Event happened: " + force); 


     if (force > Main.dropValue) 
     { 
      onDrop(force); 
     } 
    } 
}; 

public void startListener() 
{ 
    ASensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE); 
    List<Sensor> sensors = ASensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); 
    if (sensors.size() > 0) 
    { 
     sensor = sensors.get(0); 
     listening = ASensorManager.registerListener(accelEventListener, sensor, SensorManager.SENSOR_DELAY_GAME); 

    } 
} 


public class AccelBinder<S> extends Binder 
{ 
    private WeakReference<S> mService; 

    public AccelBinder (S service) 
    { 
     mService = new WeakReference<S>(service); 
    } 

    public S getService() 
    { 
     return mService.get(); 
    } 
} 

public IBinder mBinder; 

@Override 
public void onCreate() 
{ 
    startListener(); 

    mBinder = new AccelBinder<AccelService>(this); 
} 

public boolean isListening() 
{ 
    return listening; 
} 

/*@Override 
public void onStart(Intent intent, int startId) 
{ 
    Log.i("LocalService", "Received start id " + startId + ": " + intent); 
}*/ 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    Log.i("LocalService", "Received start id " + startId + ": " + intent); 
    return AccelService.START_STICKY; 
} 

@Override 
public void onDestroy() 
{ 
    if (listening) 
     stopListening(); 
    mBinder = null; 

    super.onDestroy(); 
} 

public void onDrop(double force) 
{ 
    if (!callMade) 
    { 
     Toast.makeText(this, "Phone dropped: " + force, 5000).show(); 
     Intent i = new Intent(this,Next.class); 
     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     callMade = true; 
     //stopListening(); 
     //onDestroy(); 
     //SafetyNet.ctxt.unbindService(SafetyNet.AccelWatch); 
     this.startActivity(i); 
    } 
} 

public void stopListening() 
{  

    listening = false; 
    try { 
     if (ASensorManager != null && accelEventListener != null) 
     { 
      ASensorManager.unregisterListener(accelEventListener); 
     } 
    } catch (Exception e) {}   
} 

@Override 
public IBinder onBind(Intent intent) 
{ 
    return mBinder; 
} 

} 

ответ

7

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

IF AccelBinder - это внутренний класс вашей службы, который делает его статическим внутренним классом или, как я обычно, отдельным классом. Статические внутренние классы не имеют ссылки на внешний класс. Помните, что вы пропустите свой Binder. Если ваш Binder является нестационарным внутренним классом, он ссылается на вашу Службу, чтобы она также протекала.

Я угадываю - как будто действительно дико угадывая - в отсутствие какого-либо кода, что что-то не так с управлением жизненным циклом вашей деятельности и как вы обрабатываете объекты Binder.

Что нужно иметь в виду ....

Не держите статическую ссылку на ваш объект Binder - они являются одноразовыми - получить новый пароль каждый раз, когда вы связать.

Держите свою привязку симметричной относительно жизненного цикла вашей деятельности. Если вы привязываетесь в onCreate(), отвяжите в onDestroy() (или onPause, если isFinishing()) и т. Д. Это особенно важно, если вы не понимаете, что физическое вращение телефона с помощью Sensor уничтожает вашу активность, воссоздает ее с нуля ,

Вы, кажется, слишком любите «статические» переменные класса. В Android статические вещи, как правило, приводят к утечке памяти - и если у вас есть утечка, есть контекст - все становится неприятно. Если вы хотите сохранить состояние между экземплярами одного и того же класса, используйте вместо этого предпочтения.

Например,

private static Sensor sensor; 
private static SensorManager ASensorManager; 

выбрасывается вместе между использованиями.

Удостоверяются, что вы особенно не сохраняете статическую ссылку на свою Службу в своей деятельности. Услуги - это одиночные игры по самой природе Android, если они все еще работают, вы будете получать одну и ту же услугу каждый раз, когда будете привязываться. Подсчитайте, что ваша Служба была убита ОС в определенный момент времени. Напишите свою службу, чтобы она выполняла свою работу, если она перезапускается заново.

Достаточно угадать на один день.