从服务获取活动的引用

发布于 2024-12-03 00:34:44 字数 1038 浏览 1 评论 0原文

我需要从服务获取对主要活动的引用。

这是我的设计:

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

我该怎么做?

[编辑]

感谢大家的回答! 这个应用程序是一个网络服务器,目前仅适用于线程,我想使用服务来代替,以使其在后台也能工作。 问题是我有一个类负责从资产中获取页面,要做这个操作我需要使用这个方法:

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

此时我的项目只有一个 Activity 并且没有服务,所以我可以通过主 Activity 的直接从自身引用:

WebServer ws= new DroidWebServer(8080,this);

那么,为了使该应用程序与服务一起使用,我应该在设计中更改哪些内容?

I need to get a reference to the main Activity from a Service.

This is my design:

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

How can I do this?

[EDIT]

Thanks to all for the answers!
This app is a web server, that at this moment works only with threads, and I want to use a service instead, to make it work also in the background.
The problem is that I have a class that is responsible for getting the page from assets, and to do this operation I need to use this method:

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

At this moment my project has only one Activity and no services, so I can pass the main activity's reference directly from itself:

WebServer ws= new DroidWebServer(8080,this);

So, in order to make this app work with a service, what should I change in my design?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

天暗了我发光 2024-12-10 00:34:44

你没有解释为什么你需要这个。但这绝对是糟糕的设计。存储对 Activity 的引用是您不应该对 Activity 执行的第一件事。嗯,可以,但是您必须跟踪 Activity 生命周期并在调用其 onDestroy() 后释放引用。如果您不这样做,则会出现内存泄漏(例如,当配置更改时)。而且,在调用 onDestroy() 后,Activity 被认为已死亡,而且很可能毫无用处。

因此,不要将引用存储在 Service 中。描述一下你需要实现什么目标。我确信有更好的选择。


更新

好的,所以您实际上不需要引用 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); 
     }
}

现在您可以创建 &使用来自 Service 的 WebService 实例(建议用于此类后台任务),甚至使用来自 Activity 的 WebService 实例(当涉及 Web 服务调用或长时间后台任务时,要正确使用 WebService 实例要困难得多)。

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

You didn't explain why you need this. But this is definitely bad design. Storing references to Activity is the first thing you shouldn't do with activities. Well, you can, but you must track Activity lifecycle and release the reference after its onDestroy() is called. If you are not doing this, you'll get a memory leak (when configuration changes, for example). And, well, after onDestroy() is called, Activity is considered dead and is most likely useless anyway.

So just don't store the reference in Service. Describe what you need to achieve instead. I'm sure there are better alternatives out there.


UPDATE

Ok, so you do not actually need reference to Activity. Instead you need reference to Context (which in your case should be ApplicationContext to not keep reference to Activity or any other component for that matter).

Assuming you have a separate class that handles WebService request:

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

Now you can create & use WebService instance from Service (which is recommended for such background tasks) or even from Activity (which is much trickier to get right when web service calls or long background tasks are involved).

An example with 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;
    }
}
无声情话 2024-12-10 00:34:44

要在您的服务和活动之间进行通信,您应该使用 AIDL。
有关此链接的更多信息:

编辑:(感谢 Renan Malke Stigliani)
http://developer.android.com/guide/components/aidl.html

To communicate between your service and activity you should use AIDL.
More info on this link:

EDIT: (Thanks Renan Malke Stigliani)
http://developer.android.com/guide/components/aidl.html

寻找一个思念的角度 2024-12-10 00:34:44

除非 Activity 和服务位于单独的 apk 中,否则 AIDL 就太过分了。

只需使用本地服务的绑定器即可。
(完整示例在这里: http://developer.android.com/reference/android/应用程序/Service.html)

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

The AIDL is overkill unless the activity and service are in seperate apks.

Just use a binder to a local service.
(full example here: http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }
櫻之舞 2024-12-10 00:34:44

同意伊纳扎鲁克的评论。但是,就 Activity 和 Service 之间的通信而言,您有几种选择 - AIDL(如上所述)、Messenger、BroadcastReicever 等。Messenger 方法与 AIDL 类似,但不需要您定义接口。您可以从这里开始:

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

Agree with inazaruk's comments. But, In terms of communicating between an Activity and a Service, you have a few choices - AIDL (as mentioned above), Messenger, BroadcastReicever, etc. The Messenger method is similar to AIDL but doesn't require you to define the interfaces. You can start here:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文