簡體   English   中英

Android服務的良好做法

[英]Good practices for services on Android

我目前在我的應用中使用2種服務:

1:LocationService ,基本上是試圖對用戶進行本地化,並且旨在僅在應用程序處於前台時才保持活動狀態。

2:XmppService ,它初始化與xmpp服務器的連接,接收消息,發送消息,注銷...並旨在保持活動狀態,直到用戶注銷為止。

我已經閱讀了很多文檔,但是我不清楚。

嘗試存儲LocationServiceBinder的引用時出現泄漏 ,該引用用於調用我的服務函數( 使用AIDL接口 )。 Xmpp也一樣。 當我解除綁定時,有時會得到ANR( 這似乎與我的綁定/解除綁定很奇怪的事實聯系在一起,onResume,onRestart ... )。

所有系統都在工作 ,但是我敢肯定這不是正確的方法,請我跟隨有經驗的人回到部隊的右邊! :)

干杯

UPDATE

我的位置服務會在應用啟動時綁定,以盡快獲得用戶的位置:

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 = new ServiceConnection(){

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

並取消綁定每個Activity:

if (callConnectService != null){
        unbindService(callConnectService);
        callConnectService = null;
    }

尚未在Google的官方開發指南中進行充分的文檔說明,Context.bindService()實際上是一個異步調用。 這就是將ServiceConnection.onServiceConnected()用作回調方法的原因,這意味着不會立即發生。

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()中調用MyServiceBinder.doSomething(),或通過某些用戶交互(例如,單擊按鈕)執行MyServiceBinder.doSomething(),作為調用bindService()之后且系統獲取myServiceBinder引用之前的延遲很快。 只要您不立即使用它,就可以了。

查看此SO問題CommonsWare的答案以獲取更多詳細信息。

這個線程很舊,但是我才發現它。

實際上,如果綁定了服務,則只有一種方法可以繼續生存:必須同時啟動它。 文檔尚不清楚,但是可以啟動和綁定服務。

在這種情況下,取消綁定該服務不會被破壞,而在以下情況下它將被破壞:

  • 你停止它,沒有人束縛它
  • 您解除了綁定,之前已停止。

在GitHub上制作了一個小型Service Lifecycle演示應用程序,該應用程序也可以在Google Play上使用

希望能有所幫助;)

如果您綁定到活動中的服務,則也需要解除綁定:

@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()

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進行此練習

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM