2016-12-30 13 views
0

Я унаследовал некоторый код Android, и я замечаю, что существует класс, расширяющий Сервис, но не объявленный в манифесте. Я нахожу это тревожным. Я исследовал дальше, и я вижу, что служба не объявлена ​​в манифесте, но она все еще работает!android -Инструменты создания экземпляра класса службы

что происходящий находится в деятельности onResume разработчик называет следующие:

@Override 
    protected void onResume() { 
     super.onResume(); 
mMyService = new MyService(); 
} 


@Override 
    protected void onStart() { 
     super.onStart(); 
    mMyService = new MyService(); 
} 

я никогда не видел эту практику раньше. это вызовет утечку памяти? Компоненты Android объявлены в манифесте и никогда не создаются правильно? Система позаботится об этом для вас.

Сам сервис объявляется как этот

public class MyService extends Service { 

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

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 


    //... a bunch of other methods that do stuff by calling from the "new" instance would be below. 

} 

Опять же, ничего не декларируется в манифесте. это еще один образец, и это безопасно?

ответ

2

я исследовал дальше и я вижу, что служба не объявлена ​​в манифесте пока он все еще работает!

Это «работает», потому что класс используется как обычный класс java - он имеет поля и общедоступные методы, которые вы можете назвать, но это уже не служба Android. Служба Android - это компонент, предназначенный для выполнения длительных операций в фоновом режиме, имеет жизненный цикл, а также ссылку на Context.

Например, при создании экземпляра службы с: MyService service = new MyService() вы заметите, что onCreate() метод класса не вызывается, и если вы пытаетесь сделать что-то, что включает в себя использование Context, такие как показ Toast, вы будете получить исключение.

2

Это может вызвать утечку памяти?

Не по существу. MyService не будет больше подвержен утечке, чем любой другой объект Java.

Компоненты андроида объявлены в манифесте и никогда не были эмулированы справа?

только Android компонент, который иногда сам экземпляр является BroadcastReceiver, и только если вы используете registerReceiver(). В противном случае классы framework создадут экземпляр ваших компонентов.

это еще один образец

Один из разработчиков "" с ограниченным опытом. Обычно такие вещи начинаются с того, кто нуждается в Context для чего-то другого, и поэтому они произвольно создают некоторый подкласс Activity или Service, считая, что они смогут создать экземпляр (например, new MyService()) и иметь рабочий Context. Это редко работает, так как Context не будет правильно инициализирован таким образом. Иногда сами разработчики просто копируют код, который они видели где-то в другом месте, например, смешное количество вопросов и ответов о переполнении стека вокруг GPSService, которое настроено схожим с вашим MyService.

Если предположить, что этот класс должен существовать вообще (против быть частью деятельности), я рекомендую вам:

  • Удалить extends Service

  • Удалить методы ничегонеделания, которые были отмечены а @Override, такие как onBind() и onCreate() методы в вашем фрагменте кода

  • Исправьте ошибки сборки, которые приводят к MyService больше не распространяется на Service, гарантируя, что эти методы имеют доступ к реальному объекту Context (например,, То `активность)