2011-09-04 80 views
5

我需要从服务中获取对主Activity的引用。从服务中获取Activity的引用

这是我的设计:

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

我该怎么办?

[编辑]

感谢所有的答案! 这个应用程序是一个Web服务器,在这个时候只能与线程一起工作,而我想要使用服务来使它在后台工作。 的问题是,我有一个类,该类负责获取从资产页面,无法进行此操作,我需要用这个方法:

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

这时我的项目只有一个活动,没有服务,这样我就可以直接通过自身的主要活动的参考:

WebServer ws= new DroidWebServer(8080,this); 

因此,为了使这个应用程序与服务的工作,我应该在我的设计变更?

回答

7

你没有解释为什么你需要这个。但这绝对是设计。存储对活动的引用是您首先要做的事情不应该是。那么你可以,但是你必须跟踪Activity的生命周期,并在调用onDestroy()之后释放参考。如果你不这样做,你会得到一个内存泄漏(例如,当配置发生变化时)。而且,在onDestroy()被调用之后,活动被认为是死的,而且最可能无用。

所以只是不要在服务中存储引用。请描述您需要实现的内容。我确信有更好的选择。


UPDATE

好了,你实际上并不需要参考活动。相反,你需要引用上下文(在你的情况下应该是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); 
    } 
} 

现在你可以从Service创建&使用WebService实例(推荐这样的后台任务),甚至Activity(这是更棘手在涉及Web服务调用或涉及长时间后台任务时正确使用)。

一个例子与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

我编辑了这个问题! – supergiox

+1

我已更新答案 – inazaruk

+0

谢谢!似乎没事,除了需要一个Activity的方法外:'最终光标photo = activity.managedQuery(Data.CONTENT_URI,new String [] {Photo.PHOTO},Data._ID +“=?”,new String [ ] {photoId},null);' – supergiox

2

的AIDL是矫枉过正,除非活动和服务都在单独的APK。

只需使用活页夹到本地服务。 (这里完整的例子:http://developer.android.com/reference/android/app/Service.html

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

这是如何让你做OP的要求?如果您使用更多代码示例进行编辑,我会赞成。 – 2013-02-14 07:33:09