получить ссылку на активность от службы - PullRequest
8 голосов
/ 04 сентября 2011

Мне нужно получить ссылку на основную активность из службы.

Это мой дизайн:

MainActivity.java

public class MainActivity extends Activity{
private Intent myIntent;
onCreate(){
 myIntent=new Intent(MainActivity.this, MyService.class);

 btnStart.setOnClickListener(new OnClickListener(){
  public void onClick(View V){
   startService(myIntent);
   });
}}

MyService.java

class MyService extends Service{

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

 onCreate(){
 //Here I need to have a MainActivity reference
 //to pass it to another object
 }
}

Как я могу это сделать?

[EDIT]

Спасибо всем за ответы! Это приложение представляет собой веб-сервер, который в данный момент работает только с потоками, и я хочу вместо этого использовать службу, чтобы она работала также в фоновом режиме. Проблема в том, что у меня есть класс, который отвечает за получение страницы из ресурсов, и для этой операции мне нужно использовать этот метод:

InputStream iS =myActivity.getAssets().open("www/"+filename); 

В данный момент в моем проекте есть только одно действие и нет служб, поэтому я могу передать ссылку на основное действие непосредственно из себя:

WebServer ws= new DroidWebServer(8080,this);

Итак, чтобы приложение работало со службой, что я должен изменить в своем дизайне?

Ответы [ 4 ]

9 голосов
/ 04 сентября 2011

Вы не объяснили, зачем вам это нужно. Но это определенно плохой дизайн. Хранение ссылок на Activity - это первое, что вы не должны делать с действиями. Ну, вы можете, но вы должны отслеживать жизненный цикл Activity и выпускать ссылку после того, как вызывается onDestroy(). Если вы этого не сделаете, вы получите утечку памяти (например, при изменении конфигурации). И, ну, после вызова onDestroy() активность считается мертвой и, скорее всего, в любом случае бесполезной.

Так что просто не храните ссылку в Сервисе. Опишите, что вам нужно достичь вместо этого. Я уверен, что есть лучшие альтернативы.


UPDATE

Хорошо, так что вам на самом деле не нужна ссылка на Activity. Вместо этого вам нужна ссылка на Context (который в вашем случае должен быть ApplicationContext, чтобы не сохранять ссылку на Activity или любой другой компонент в этом отношении).

Предполагается, что у вас есть отдельный класс, который обрабатывает запрос WebService:

class WebService 
{   
     private final Context mContext;
     public WebService(Context ctx) 
     {
        //The only context that is safe to keep without tracking its lifetime
        //is application context. Activity context and Service context can expire
        //and we do not want to keep reference to them and prevent 
        //GC from recycling the memory.
        mContext = ctx.getApplicationContext(); 
     }

     public void someFunc(String filename) throws IOException 
     {
         InputStream iS = mContext.getAssets().open("www/"+filename); 
     }
}

Теперь вы можете создавать и использовать экземпляр WebService из Service (что рекомендуется для таких фоновых задач) или даже из Activity (что гораздо сложнее получить, когда речь идет о вызовах веб-службы или длинных фоновых задачах).

Пример с Service:

class MyService extends Service
{
    WebService mWs;
    @Override
    public void onCreate()
    {
        super.onCreate();
        mWs = new WebService(this);

       //you now can call mWs.someFunc() in separate thread to load data from assets.
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }
}
2 голосов
/ 24 сентября 2012

AIDL является излишним, если действие и служба не находятся в отдельных apks.

Просто используйте связыватель для локальной службы.(полный пример здесь: http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }
2 голосов
/ 04 сентября 2011

Для связи между вашим сервисом и деятельностью вы должны использовать AIDL.Больше информации по этой ссылке:

РЕДАКТИРОВАТЬ: (Спасибо Ренан Малке Стиглиани) http://developer.android.com/guide/components/aidl.html

0 голосов
/ 04 сентября 2011

Согласен с комментариями Иназарука.Но с точки зрения связи между Активностью и Сервисом у вас есть несколько вариантов - AIDL (как упомянуто выше), Messenger, BroadcastReicever и т. Д. Метод Messenger аналогичен AIDL, но не требует определения интерфейсов.Вы можете начать здесь:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html

...