2011-09-04 13 views
5

Necesito obtener una referencia a la actividad principal de un servicio.obtener la referencia de actividad de un servicio

Ésta es mi diseño:

MainActivity.java

public class MainActivity extendsActivity{ 
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 
} 
} 

¿Cómo se puede hacer?

[EDIT]

Gracias a todos por las respuestas! Esta aplicación es un servidor web, que en este momento funciona solo con hilos, y quiero usar un servicio en su lugar, para que funcione también en segundo plano. El problema es que tengo una clase que es responsable para obtener la página de los activos, y para hacer esta operación que necesito utilizar este método:

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

En este momento mi proyecto tiene una sola actividad y sin los servicios, por lo que pueden pasar a la principal referencia de la actividad directa de sí mismo:

WebServer ws= new DroidWebServer(8080,this); 

por lo tanto, con el fin de hacer que trabaja con un servicio de esta aplicación, lo que debo cambiar en mi diseño?

Respuesta

7

Usted no explicó por qué necesita esto. Pero esto es definitivamente mal diseño. Almacenar referencias a Actividad es lo primero que no debe hacer con actividades. Bien, puede hacerlo, pero debe realizar un seguimiento del ciclo de vida de la actividad y liberar la referencia después de llamar a su onDestroy(). Si no lo hace, obtendrá una pérdida de memoria (cuando la configuración cambia, por ejemplo). Y, bueno, después de que se llame al onDestroy(), la actividad se considera muerta y, de todos modos, es inútil.

Así que no almacene la referencia en el Servicio. Describe lo que necesitas lograr en su lugar. Estoy seguro de que hay mejores alternativas por ahí.


ACTUALIZACIÓN

Ok, por lo que en realidad no necesita referencia a la actividad. En su lugar, necesita referencia a Contexto (que en su caso debe ser ApplicationContext para no mantener referencia a Activity o cualquier otro componente para ese asunto).

Asumiendo que tiene una clase separada que se encarga de solicitud de servicio Web:

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

Ahora puede crear & ejemplo, el uso de WebService de Service (que se recomienda para este tipo de tareas en segundo plano) o incluso de Activity (que es mucho más complicado para hacerlo bien cuando se trata de llamadas a servicios web o tareas de fondo largas).

Un ejemplo con 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; 
    } 
} 
+0

¡Edité la pregunta! – supergiox

+1

He actualizado la respuesta – inazaruk

+0

¡Gracias! Parece estar bien, excepto por un método que necesita una Actividad: 'Foto del Cursor final = activity.managedQuery (Data.CONTENT_URI, new String [] {Photo.PHOTO}, Data._ID +" =? ", New String [ ] {photoId}, null); ' – supergiox

2

El AIDL es un exceso menos que la actividad y el servicio están en un apk separadas.

Simplemente use una carpeta para un servicio local. (ejemplo completo aquí: http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder { 
     LocalService getService() { 
      return LocalService.this; 
     } 
    } 
+1

¿Cómo te permite eso hacer lo que OP está pidiendo? Voy a votar mejor si editas con más ejemplos de código. –

Cuestiones relacionadas