2013-07-05 72 views
1

我想了解如何在Android的服務工作,並宣讀了綁定服務的Android文檔: http://developer.android.com/guide/components/bound-services.html 對於以後的項目,我需要在不斷的後臺運行,並可以通過進行交互的服務應用程序。該文檔聲明您還可以綁定到由startService()啓動的服務。但是,我有一些麻煩讓它正常工作。Android的服務壽命

服務很簡單。它的唯一目的是提供一個計數器(我已經跳過了進口不亂的代碼不必要地):

package com.test.servicetester; 

public class LocalService extends Service { 
private final IBinder mBinder = new LocalBinder(); 

private int mCounter = 0; 

public class LocalBinder extends Binder { 
    LocalService getService() { 
     // Return this instance of LocalService so clients can call public methods 
     return LocalService.this; 
    } 
} 

private void createNotification(){ 

    Intent intent = new Intent(this, MainActivity.class); 
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0); 

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) 
     .setSmallIcon(R.drawable.roll) 
     .setContentTitle("my notification") 
     .setContentText("Hello World!") 
     .setProgress(100, 33, false) 
     .setOngoing(true) 
     .addAction(R.drawable.roll, "Titel", pIntent); 

    NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
    mNotificationManager.notify(1337, mBuilder.build()); 
} 

@Override 
public void onStart(Intent intent, int startId){ 
    createNotification(); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    //createNotification(); 
    Toast.makeText(this, "The service has been bound.", Toast.LENGTH_SHORT).show(); 
    return mBinder; 
} 

/** method for clients */ 
public int getNumber() { 
    mCounter++; 
    return mCounter; 
} 

@Override 
public void onDestroy(){ 
    NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
    mNotificationManager.cancelAll(); 
} 
} 

從中我控制服務包含兩個按鈕,一個得到一個隨機數的活性,第二個殺服務:

package com.wursti.servicetest0r; 

import com.wursti.servicetest0r.LocalService.LocalBinder; 

public class MainActivity extends Activity { 

LocalService mService; 
boolean mBound = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

@Override 
protected void onStart(){ 
    super.onStart(); 
    // bind to local service 
    if(!isServiceRunning()) 
     startService(new Intent(this,LocalService.class)); 
    else 
     Toast.makeText(this, "Service is already running.", Toast.LENGTH_SHORT).show(); 

    Intent intent = new Intent(this, LocalService.class); 
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
} 

private boolean isServiceRunning(){ 
    ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 
    for(RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
     if(LocalService.class.getName().equals(service.service.getClassName())) { 
      return true; 
     } 
    } 
    return false; 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    // unbind from the service 
    if(mBound) { 
     unbindService(mConnection); 
     mBound = false; 
    } 
} 

public void onButtonClick(View v) { 
    if(mBound) { 
     int num = mService.getNumber(); 
     Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); 
    } 
} 

public void onKillServiceClick(View v) { 
    mBound = false; // <-- this line was edited because of a comment 
    stopService(new Intent(this, LocalService.class)); 
    unbindService(mConnection); 
} 

/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     // we've bound to LocalService, cast the IBinder and get LocalService instance 
     LocalBinder binder = (LocalBinder) service; 
     mService = binder.getService(); 
     mBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName arg0){ 
     mBound = false; 
    } 
}; 
} 

發生的以下的事情: 我啓動應用程序和服務啓動,並出現通知。如果我點擊相應的按鈕,我會得到正確計數的數字。我可以切換回啓動程序,重新打開應用程序,並會收到服務已啓動並已成功綁定的消息。但是,如果我點擊殺服務按鈕,通知就會消失,但如果使用其他按鈕,我仍然可以從服務中獲取號碼。 這是什麼使我困惑......通知在服務onDestroy()方法中被銷燬。因此它不應該存在?爲什麼它仍然可以提供數字? 查殺服務後,如果我切換到啓動應用程序崩潰和logcat的說:

07-05 10:44:21.964: E/AndroidRuntime(792): java.lang.RuntimeException: Unable to stop activity {com.wursti.servicetest0r/com.wursti.servicetest0r.MainActivity}: java.lang.IllegalArgumentException: Service not registered: [email protected] 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3415) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3469) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread.access$1200(ActivityThread.java:141) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.os.Handler.dispatchMessage(Handler.java:99) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.os.Looper.loop(Looper.java:137) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread.main(ActivityThread.java:5041) 
07-05 10:44:21.964: E/AndroidRuntime(792): at java.lang.reflect.Method.invokeNative(Native Method) 
07-05 10:44:21.964: E/AndroidRuntime(792): at java.lang.reflect.Method.invoke(Method.java:511) 
07-05 10:44:21.964: E/AndroidRuntime(792): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
07-05 10:44:21.964: E/AndroidRuntime(792): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
07-05 10:44:21.964: E/AndroidRuntime(792): at dalvik.system.NativeStart.main(Native Method) 
07-05 10:44:21.964: E/AndroidRuntime(792): Caused by: java.lang.IllegalArgumentException: Service not registered: [email protected] 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:921) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ContextImpl.unbindService(ContextImpl.java:1451) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.content.ContextWrapper.unbindService(ContextWrapper.java:484) 
07-05 10:44:21.964: E/AndroidRuntime(792): at com.wursti.servicetest0r.MainActivity.onStop(MainActivity.java:61) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1205) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.Activity.performStop(Activity.java:5246) 
07-05 10:44:21.964: E/AndroidRuntime(792): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3410) 
07-05 10:44:21.964: E/AndroidRuntime(792): ... 11 more 

老實說,我沒有就如何從這裏繼續任何想法,任何幫助表示讚賞:)

+0

你註冊了AndroidManifest.xml中的LocalService嗎? –

+0

是的,我想否則我甚至不能啓動服務?我也有這個在清單文件中: android:enabled =「true」 b0wter

+0

你可以嘗試先交換unbindService,然後stopService() –

回答

2

unbindService(mConnection);

onStop即使在您之前正在查殺服務時也會被調用。

可能是錯誤。

嘗試處理!

+0

解決了關閉應用程序時崩潰的部分!謝謝 – b0wter

+1

我選擇了這個作爲答案,因爲它解決了一半的問題。爲你的努力。 – b0wter