2011-06-18 12 views
0

Servicesについては、複数のアクティビティを同じサービスにバインドできますが、機能しません。私のBackgroundServiceがサービスを拡張する価値があるのか​​。私のMainActivityからサービスへの複数のアクティビティの開始/バインド

私は次のようにサービスを開始します。

Intent backgroundService = new Intent(MainActivity.this, BackgroundService.class); 
backgroundService.putExtra(BackgroundService.EXTRA_MESSENGER_MAINACTIVITY, new Messenger(mainHandler)); 
startService(backgroundService); 

をそれから私は、次のようにこれと同じサービスをバインドしようとする別の活動から:

Intent backgroundService = new Intent(RcvMessages.this, BackgroundService.class); 
backgroundService.putExtra(BackgroundService.EXTRA_MESSENGER_RCVMESSAGES, new Messenger(rcvHandler)); 
startService(backgroundService); 

私の理解では、それぞれに結合していることです上記のように、サービスにはそれ自身のハンドラがあります。しかし、それは動作しません。最初のハンドラーのみが動作します。私は間違って何をしていますか?

@フェミ氏は、「あなたはBackgroundServiceクラスにインテントを追加してメッセンジャーを渡していますが、そのMessengerで何をするのかを理解している組み込みのAndroidコードはありません。これはBackgroundService実装BackgroundServiceのコードは何ですか?また、渡されたMessengerインスタンスはどうしますか? @Femiは私のBackgroundSerive、特にonStartCommand()を見て:

/************************************************************************************************** 
* File: BackgroundService.java 
* Application: BackgroundService 
* Description: This file contains the background Service that is launched by the MainActivity's 
*  bind button. 
**************************************************************************************************/ 

package com.marie.mainactivity; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.os.RemoteException; 
import android.util.Log; 

/* 
* Class: BackgroundService 
* Purpose: Using the onStart() method the BackgroundService gets the reference to the 
*  Messenger instance that was passed to BackgroundService. The messenger is then 
*  used by the ServiceWorker() thread to send messages to the handler that is defined 
*  in the MainActivity class. 
*/ 
public class BackgroundService extends Service { 
    private NotificationManager notificationMgr; 

    public static final String EXTRA_MESSENGER_MAINACTIVITY = "com.marie.mainactivity.EXTRA_MESSENGER_MAINACTIVITY"; 
    private Messenger messenger_mainactivity; 

    public static final String EXTRA_MESSENGER_RCVMESSAGES = "com.marie.mainactivity.EXTRA_MESSENGER_RCVMESSAGES"; 
    private Messenger messenger_rcvmessages; 

    public static final String EXTRA_SONG = "com.marie.mainactivity.EXTRA_SONG"; 
    int song = 0; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     notificationMgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 

     displayNotificationMessage("starting Background Service"); 

     Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService"); 
     thr.start(); 
    } 

    /* 
    * This is the ServiceWorker thread that passes messages to the handler defined in 
    * the MainActivity class. 
    * NOTE: Instead of passing messages to a handler in MainActivity I would like 
    * it to pass messages to a handler defined in the RcvMessages activity. 
    */ 
    class ServiceWorker implements Runnable 
    { 
     public void run() { 
      // do background processing here... something simple 

      // send a message to the handler defined in the MainActivity activity 
      if (messenger_mainactivity != null) 
      { 
       try { 
        Message msg1 = Message.obtain(); 
        msg1.obj = "SongData"; 
        msg1.arg1 = 1000; 
        messenger_mainactivity.send(msg1); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } catch (NullPointerException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       Log.e("messenger_mainactivity", "null"); 
      } 

      // send a message to the handler defined in the RcvMessages activity 
      if (messenger_rcvmessages != null) 
      { 
       try { 
        Message msg1 = Message.obtain(); 
        msg1.obj = "Song"; 
        msg1.arg1 = song; 
        messenger_rcvmessages.send(msg1); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } catch (NullPointerException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       Log.e("messenger_rcvmessages", "null"); 
      } 

      // stop the service when done... 
      // BackgroundService.this.stopSelf(); 
      // Or use the unbindBtn in the MainActivity class. 
     } 
    } 

    @Override 
    public void onDestroy() 
    { 
     displayNotificationMessage("stopping Background Service"); 
     super.onDestroy(); 
    } 

    /* 
    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
    } 
    */ 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 

     Bundle extras = intent.getExtras(); 
     Messenger messenger; 

     messenger = (Messenger)extras.get(EXTRA_MESSENGER_MAINACTIVITY); 
     if (messenger != null) { 
      messenger_mainactivity = messenger; 
     } 

     messenger = (Messenger)extras.get(EXTRA_MESSENGER_RCVMESSAGES); 
     if (messenger != null) { 
      messenger_rcvmessages = messenger; 
      song = extras.getInt(EXTRA_SONG); 
     } 

     return START_NOT_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    private void displayNotificationMessage(String message) 
    { 
     Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis()); 

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

     notification.setLatestEventInfo(this, "Background Service", message, contentIntent); 

     notificationMgr.notify(R.id.app_notification_id, notification); 
    } 
} 

ここでは、全体のコードです:

/************************************************************************************************** 
* File: MainActivity.java 
* Application: BackgroundService 
* Description: This file contains the main activity that is run when the BackgroundService 
*  application is launched. 
**************************************************************************************************/ 

package com.marie.mainactivity; 

import com.marie.mainactivity.BackgroundService; 
import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.os.Messenger; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

/* 
* Class: MainActivity 
* Purpose: Using a button, the MainActivity class starts the backgroundService and 
*  the RcvMessages activity. Using another button MainActivity stops the backgroundService. 
*  NOTE: RcvMessages is only a stub that does nothing but display a simple message. 
* Handler: MainActivity defines and provides a reference to "handler" for the backgroundService. 
*/ 
public class MainActivity extends Activity { 
    private static final String TAG = "MainActivity"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     /* 
     * The bind button: bindBtn 
     * Clicking this button starts the background Service and launches the 
     * RcvMessages activity. NOTE: RcvMessages is only a stub so far. 
     */ 
     Button bindBtn = (Button)findViewById(R.id.bindBtn); 
     bindBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // Start the background Service for sending canned messages to the handler as a test. 
       Log.d(TAG, "starting service"); 
       Intent backgroundService = new Intent(MainActivity.this, BackgroundService.class); 
       backgroundService.putExtra(BackgroundService.EXTRA_MESSENGER_MAINACTIVITY, new Messenger(mainHandler)); 
       startService(backgroundService); 

       // Start the RcvMessages activity to receive messages from the handler. But how??? 
       Intent messages = new Intent(MainActivity.this, RcvMessages.class); 
       messages.putExtra(RcvMessages.EXTRA_SONG, 10); 
       startActivity(messages); 
      } 
     }); 

     /* 
     * The unbind button: unbindBtn 
     * Clicking this button stops the background Service. 
     */ 
     Button unbindBtn = (Button)findViewById(R.id.unbindBtn); 
     unbindBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       // Stop the background Service 
       Intent backgroundService = new Intent(MainActivity.this, BackgroundService.class); 
       stopService(backgroundService); 
      } 
     }); 
    } 

    /* 
    * This is the handler to be passed to the background Service via a Messenger. 
    * NOTE: I want it to send messages to my RcvMessages activity. 
    */ 
    private Handler mainHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      // simple handler test (does not send messages to RcvMessages activity 
      String obj = (String) msg.obj; 
      int arg1 = msg.arg1; 
      Log.i("handleMessge_mainactivity", "obj: " + obj + " " + "arg1: " + arg1); 
     } 
    }; 
} 


/************************************************************************************************** 
* File: BackgroundService.java 
* Application: BackgroundService 
* Description: This file contains the background Service that is launched by the MainActivity's 
*  bind button. 
**************************************************************************************************/ 

package com.marie.mainactivity; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.os.RemoteException; 
import android.util.Log; 

/* 
* Class: BackgroundService 
* Purpose: Using the onStart() method the BackgroundService gets the reference to the 
*  Messenger instance that was passed to BackgroundService. The messenger is then 
*  used by the ServiceWorker() thread to send messages to the handler that is defined 
*  in the MainActivity class. 
*/ 
public class BackgroundService extends Service { 
    private NotificationManager notificationMgr; 

    public static final String EXTRA_MESSENGER_MAINACTIVITY = "com.marie.mainactivity.EXTRA_MESSENGER_MAINACTIVITY"; 
    private Messenger messenger_mainactivity; 

    public static final String EXTRA_MESSENGER_RCVMESSAGES = "com.marie.mainactivity.EXTRA_MESSENGER_RCVMESSAGES"; 
    private Messenger messenger_rcvmessages; 

    public static final String EXTRA_SONG = "com.marie.mainactivity.EXTRA_SONG"; 
    int song = 0; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     notificationMgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 

     displayNotificationMessage("starting Background Service"); 

     Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService"); 
     thr.start(); 
    } 

    /* 
    * This is the ServiceWorker thread that passes messages to the handler defined in 
    * the MainActivity class. 
    * NOTE: Instead of passing messages to a handler in MainActivity I would like 
    * it to pass messages to a handler defined in the RcvMessages activity. 
    */ 
    class ServiceWorker implements Runnable 
    { 
     public void run() { 
      // do background processing here... something simple 

      // send a message to the handler defined in the MainActivity activity 
      if (messenger_mainactivity != null) 
      { 
       try { 
        Message msg1 = Message.obtain(); 
        msg1.obj = "SongData"; 
        msg1.arg1 = 1000; 
        messenger_mainactivity.send(msg1); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } catch (NullPointerException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       Log.e("messenger_mainactivity", "null"); 
      } 

      // send a message to the handler defined in the RcvMessages activity 
      if (messenger_rcvmessages != null) 
      { 
       try { 
        Message msg1 = Message.obtain(); 
        msg1.obj = "Song"; 
        msg1.arg1 = song; 
        messenger_rcvmessages.send(msg1); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } catch (NullPointerException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       Log.e("messenger_rcvmessages", "null"); 
      } 

      // stop the service when done... 
      // BackgroundService.this.stopSelf(); 
      // Or use the unbindBtn in the MainActivity class. 
     } 
    } 

    @Override 
    public void onDestroy() 
    { 
     displayNotificationMessage("stopping Background Service"); 
     super.onDestroy(); 
    } 

    /* 
    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
    } 
    */ 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 

     Bundle extras = intent.getExtras(); 
     Messenger messenger; 

     messenger = (Messenger)extras.get(EXTRA_MESSENGER_MAINACTIVITY); 
     if (messenger != null) { 
      messenger_mainactivity = messenger; 
     } 

     messenger = (Messenger)extras.get(EXTRA_MESSENGER_RCVMESSAGES); 
     if (messenger != null) { 
      messenger_rcvmessages = messenger; 
      song = extras.getInt(EXTRA_SONG); 
     } 

     return START_NOT_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    private void displayNotificationMessage(String message) 
    { 
     Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis()); 

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

     notification.setLatestEventInfo(this, "Background Service", message, contentIntent); 

     notificationMgr.notify(R.id.app_notification_id, notification); 
    } 
} 


/************************************************************************************************** 
* File: RcvMessages.java 
* Application: BackgroundService 
* Description: This file contains stub code that displays a test message in an EditText. 
**************************************************************************************************/ 

package com.marie.mainactivity; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.os.Messenger; 
import android.text.InputType; 
import android.util.Log; 
import android.widget.EditText; 

/* 
* Class: RcvMessages 
* Purpose: RcvMessages is stub code that I want to extend in some way to receive messages from 
*  the background Service. 
*  NOTE: I don't know who to do this. 
*/ 
public class RcvMessages extends Activity { 

    public static final String EXTRA_SONG = "com.marie.mainactivity.EXTRA_SONG"; 
    EditText myText; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.messages); 

     myText = (EditText)findViewById(R.id.my_text); 

     myText.setSingleLine(); 
     myText.setInputType(InputType.TYPE_NULL); 

     // Display a simple test message for now. 
     // myText.setText("RcvMessages here"); 
    } 

    @Override 
    public void onStart(){ 
     super.onStart(); 
     Bundle extras = getIntent().getExtras(); 
     int song = (Integer) extras.get(EXTRA_SONG); 
     //myText.setText("song " + song); 

     // Start the background Service for sending canned messages to the handler as a test. 
     Intent backgroundService = new Intent(RcvMessages.this, BackgroundService.class); 
     backgroundService.putExtra(BackgroundService.EXTRA_MESSENGER_RCVMESSAGES, new Messenger(rcvHandler)); 
     backgroundService.putExtra(BackgroundService.EXTRA_SONG, song); 
     bindService(backgroundService); 
    } 

    private void bindService(Intent backgroundService) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     myText.setText(""); 
    } 

    /* 
    * This is the handler to be passed to the background Service via a Messenger. 
    * NOTE: I want it to send messages to my RcvMessages activity. 
    */ 
    private Handler rcvHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      // simple handler test 
      String song = (String) msg.obj; 
      int songNum = msg.arg1; 
      Log.i("handleMessage_rcvmessages", "songNum: " + songNum); 

      myText.setText(song + " " + songNum); 
     } 
    }; 

} 
+0

? –

+0

@Jamesハンドラの1つだけが動作します。 – Marie

答えて

1

あなたは(つまり、bindServiceを使用して行われている)あなたがサービスにバインドされていませんが、サービスを開始しようとしています。バインドする場合は、bindServiceを使用して、javadocと指定したリンクからその動作を読み込んでください。

これまでのところ、Handlerは動作しません。これはBackgroundServiceの実装に依存します。

+0

@Femiあなたはいくつかの詳細を提供してくれますか? 「これはBackgroundServiceの実装に依存しますか?」とはどういう意味ですか? – Marie

+0

'Messenger'を' BackgroundService'クラスの 'Intent'として余分に渡していますが、そのMessengerで何をすべきかを理解するためのAndroidコードは組み込まれていません。これはBackgroundService実装で提供する必要があります。 'BackgroundService'のコードは何ですか?それが渡される' Messenger'インスタンスとは何をしていますか? – Femi

+0

@Femi私はそれに応じて私の質問を修正します。 – Marie

0

私は正常にこのように私のサービスへの取り組みをバインドすることができます:あなたがこれを行うとどうなり

bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); 
関連する問題