首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android上服务的良好实践

Android上服务的良好实践
EN

Stack Overflow用户
提问于 2011-12-01 12:59:07
回答 3查看 4.1K关注 0票数 2

我目前在我的应用程序中使用两个服务:

1: LocationService,基本上是试图将用户本地化,目的是只在应用程序处于前台时才能存活。

2: XmppService,它包含与xmpp服务器的连接,接收消息,发送消息,注销.并希望在用户注销之前保持存活。

我已经读了很多文档,但是我不能说清楚。

当我试图存储用于调用我的服务函数(使用AIDL接口)的引用时,正在发生泄漏。Xmpp也一样。当我解除绑定时,有时我会得到ANR (这看起来与我的绑定/取消绑定是奇怪的,onResume,onRestart .)联系在一起的。

所有的系统都在运行,但我确信这不是正确的方法,我很乐意跟随有经验的人回到部队的右边!)

干杯

更新

我的位置服务在应用程序启动时绑定,以尽可能快地获得用户的位置:

代码语言:javascript
运行
复制
if(callConnectService == null) {
            callConnectService = new ServiceConnection() {
                public void onServiceConnected(ComponentName name, IBinder binder) {
                    locationServiceBinder = LocationServiceBinder.Stub.asInterface(binder);
                    try {
                        global.setLocationBinder(locationServiceBinder); 
                        global.getLocationBinder().startLocationListener();
                    } catch (Exception e){
                        Log.e(TAG, "Service binder ERROR");
                    }
                }

                public void onServiceDisconnected(ComponentName name) {
                    locationServiceBinder = null;
                }
            };
        }

        /* Launch Service */
        aimConServ =  new Intent(this, LocationService.class);
        boolean bound = bindService(aimConServ,callConnectService,BIND_AUTO_CREATE);

当用户登录时,启动我的Xmpp服务:

callConnectService =新的ServiceConnection() {

代码语言:javascript
运行
复制
            public void onServiceConnected(ComponentName name, IBinder binder) {
                try {
                    Log.d(TAG, "[XMPP_INIT] Complete.");
                    global.setServiceBinder(ConnectionServiceBinder.Stub.asInterface(binder)); 
                    //Connect to XMPP chat
                    global.getServiceBinder().connect();
                } catch (Exception e){
                    Log.e(TAG, "Service binder ERROR ");
                    e.printStackTrace();
                }
            }

            public void onServiceDisconnected(ComponentName name) {
                Log.e(TAG, "Service binder disconnection ");
            }
        };

        /* Launch Service */
        Intent aimConServ =  new Intent(MMWelcomeProfile.this, XmppService.class);
        bound = bindService(aimConServ,callConnectService,Context.BIND_AUTO_CREATE);

并解除对每项活动的约束:

代码语言:javascript
运行
复制
if (callConnectService != null){
        unbindService(callConnectService);
        callConnectService = null;
    }
EN

回答 3

Stack Overflow用户

发布于 2011-12-01 20:18:53

谷歌的官方开发指南( Context.bindService()实际上是一个异步调用)中并没有详细说明这一点。这就是为什么ServiceConnection.onServiceConnected()被用作回调方法的原因,这意味着不会立即发生。

代码语言:javascript
运行
复制
public class MyActivity extends Activity {
  private MyServiceBinder myServiceBinder;

  protected ServiceConnection myServiceConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
      myServiceBinder = (MyServiceBinderImpl) service;
    }

    ... ...
  }

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // bindService() is an asynchronous call. myServiceBinder is resoloved in onServiceConnected()
    bindService(new Intent(this, MyService.class),myServiceConnection, Context.BIND_AUTO_CREATE);
    // You will get a null point reference here, if you try to use MyServiceBinder immediately.
    MyServiceBinder.doSomething(); // <-- not yet resolved so Null point reference here
  }
}

解决方法是在myServiceConnection.onServiceConnected()中调用myServiceConnection.onServiceConnected(),或者通过某些用户交互(例如按钮单击)执行MyServiceBinder.doSomething(),因为在调用bindService()之后以及系统获得myServiceBinder引用之前的滞后时间很快就会到来。只要你不立即使用它,你就应该没事。

看看这个,所以询问公益性回答以获得更多的细节。

票数 1
EN

Stack Overflow用户

发布于 2012-11-21 14:41:19

这条线很旧,但我刚发现。

事实上,如果你的服务是有约束的,那么只有一种方式可以让它继续存在:它也必须开始。文档对此并不十分清楚,但是可以同时启动和绑定服务。

在这种情况下,当您解除绑定时,服务将不会被销毁,当您解除绑定时,它将被销毁:

  • 如果你阻止它,就没有人能约束它。
  • 你解除了它的束缚,它以前就被停止了。

我制作了一个小型服务生命周期演示应用程序论GitHub,它也可以在Google Play上使用。

希望有帮助;)

票数 0
EN

Stack Overflow用户

发布于 2012-12-27 16:13:16

如果绑定到活动中的服务,也需要解除绑定:

代码语言:javascript
运行
复制
@Override
protected void onResume() {

    Log.d("activity", "onResume");
    if (locationServiceBinder == null) {
        doBindLocationService();
    }
            super.onResume();
}

@Override
protected void onPause() {

    Log.d("activity", "onPause");
    if (locationServiceBinder  != null) {
        unbindService(callConnectService);
        locationServiceBinder = null;
    }
    super.onPause();
}

其中doBindLocationService()

代码语言:javascript
运行
复制
public void doBindLocationService() {
    Log.d("doBindService","called");

    aimConServ =  new Intent(this, LocationService.class);
    // Create a new Messenger for the communication back
    // From the Service to the Activity
    bindService(aimConServ, callConnectService, Context.BIND_AUTO_CREATE);
}

您也需要为您的XmppService进行此练习。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8341782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档