2011-10-15 41 views
0

首先,我试着搜索这个ans并不成功。如果我的问题已经回答了,有人可以请我指出它吗?非常感谢你通过观察这个来帮助我,或者通过掠过这些并指引我朝着正确的方向。我真的很感激!在AlertDialog中启动一个服务并绑定一个外部活动

我的困境:我有一个活动,并在该活动有listview。该列表视图中有多个项目,最需要调用AlertDialog。 AlertDialog调用一个服务,说:“嘿,你需要更新一些数据。”该服务会侦听并成功执行更新。

问题在于我的活动不承认服务。我想知道的是,我并不完全了解服务的运作方式,并且如果您可以将相同的服务启用/运行多次。

请注意,我的示例与The Android Dev Reference for Service上的想法有些类似。

的实施例:

public class MyActivity extends Activity implements IMainActivity 
    { 
     ListView _list; 

     private RefreshConnector _serviceConnector; 

     private boolean _isBound; 

     public MyActivity() {} 

     public fillList() 
      { 
        //this won't trigger within the service 
      } 

      private void doBindService() 
      { 
        // Establish a connection with the service. We use an explicit 
        // class name because we want a specific service implementation that 
        // we know will be running in our own process (and thus won't be 
        // supporting component replacement by other applications). 
        getApplicationContext().bindService(new Intent(this, UpdateScheduleService.class), _serviceConnector, BIND_AUTO_CREATE); 
        _isBound= true; 
      } 

      private void doUnbindService() 
      { 
        if (_isScheduleBound) 
        { 
          // Detach our existing connection. 
          getApplicationContext().unbindService(_serviceConnector); 
          _isBound= false; 
        } 
      } 

      @Override 
      protected void onDestroy() 
      { 
        super.onDestroy(); 
        doUnbindService(); 
      } 

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

        _isBound= false; 

        _list = (ListView) findViewById(R.id.TheList); 
        _list.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        { 
          public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) 
          { 
            if (view != null) 
            { 
              CheckBox selectedFlag = (CheckBox) view.findViewById(R.id.selectedItem); 
              selectedFlag.setOnClickListener(new View.OnClickListener() 
              { 
                public void onClick(View view) 
                { 
                  doBindService(); 
                  Bundle extras = new Bundle(); 
                  extras.putBoolean(BundleLocations.BUNDLE_ENABLED, ((CheckBox) view).isChecked()); 
                  extras.putLong(BundleLocations.BUNDLE_SCHEDULE_ID, 123); //123 is an example of an id being passed 
                  extras.putString(BundleLocations.ACTION, BundleLocations.ACTION_SELECTED); 
                  Intent updateSelection = new Intent("ChangeItems"); 
                  updateSelection.putExtras(extras); 
                  view.getContext().startService(updateSelection); 
                } 
              }); 

              TextView description = (TextView) view.findViewById(R.id.description); 
              description.setText(s.getDescription()); 
              description.setOnClickListener(new View.OnClickListener() 
              { 
                public void onClick(View view) 
                { 
                  doBindService(); 
                  ChangeDescriptionDialog dia = new ChangeDescriptionDialog(view.getContext()); 
                  dia.setTitle(view.getContext().getResources().getString(R.string.DESCRIPTION_TITLE)); 
                  dia.setAction(BundleLocations.ACTION_DESCRIPTION); 
                  dia.setDescription("something new"); //simplified for example... 
                  dia.create(); 
                  dia.show(); 
                } 
              }); 
            } 
          } 
        }; 
      } 

RefreshConnector:

public class RefreshConnector implements ServiceConnection 
{ 
    private UpdateService service; 

    public IMainActivity getActivity() 
    { 
     return activity; 
    } 

    public void setActivity(IMainActivity value) 
    { 
     this.activity = value; 
    } 

    public UpdateScheduleService getService() 
    { 
     return service; 
    } 

    private IMainActivity activity; 

    public void onServiceConnected(ComponentName componentName, IBinder iBinder) 
    { 
     service = ((UpdateService.UpdateBinder)iBinder).getService(); 

     if(activity != null) 
      activity.fillList(); 
    } 

    public void onServiceDisconnected(ComponentName componentName) 
    { 
     service = null; 
    } 
} 

的UpdateService

public class UpdateService extends Service 
{ 
    final public IBinder binder = new UpdateBinder(); 

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

    public class UpdateBinderextends Binder 
    { 
     public UpdateService getService() 
     { 
      return UpdateService .this; 
     } 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     if (intent == null) 
     { 
      stopSelf(); 
      return START_STICKY; 
     } 

     if(action.equals(BundleLocations.ACTION_SELECTED)) 
     { 
      long id = intent.getExtras().getLong(BundleLocations.BUNDLE_ID); 
      boolean enabled = intent.getExtras().getBoolean(BundleLocations.BUNDLE_ENABLED); 

      if(id < 0) 
      { 
       return START_STICKY; 
      } 

      String item = intent.getExtras().getString(BundleLocations.BUNDLE_ITEM); 

      if (item == null || action.equals("")) return START_STICKY; 

      //do some work with saving the description, which it does 

      return START_STICKY; 
     } 

     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
    } 
} 

DescriptionDialog截断(构造),同时,这是从AlertDialog.Builder类延长。我也有一个在所有基本上存储_context的对话框中常见的类。所以在这里的情况下,上下文保存在超级。 _context受保护...

public ChangeDescriptionDialog(Context context) 
    { 
     super(context); 

     DialogInterface.OnClickListener onClickListenerPositive = new DialogInterface.OnClickListener() 
     { 
      public void onClick(DialogInterface dialog, int id) 
      { 
       //dispatch change 
       Intent ChangeItems = new Intent("ChangeItems"); 
       Bundle extras = new Bundle(); 
        extras.putParcelable(BundleLocations.BUNDLE_ITEM, _description); 
       extras.putString(BundleLocations.ACTION, _action); 
       ChangeItems.putExtras(extras); 

       // 
       // my question is partly here 
       // I start this service... 
       // 
       // How would my activity see it... right now it doesn't seem that way even though I do the binding before this call 
       // 
       _context.startService(ChangeItems); 
     } 
    }; 

    this.setPositiveButton(context.getResources().getString(R.string.DIALOG_POS), onClickListenerPositive); 
} 

再次注意发生弹出之前发生的绑定。第二,请注意我在绑定中启动服务。我做错了什么或只是没有得到?

再次谢谢大家, 凯利

+0

你的服务更新数据后你想要做什么? – Noel

+0

嗨诺埃尔,我想有活动刷新数据列表 – KellyTheDev

回答

0

还有一个更简单的方法做你想做的事情,不需要绑定服务的。

首先,您应该扩展IntentService而不是Service。这将确保您的服务不会在UI线程上运行。您将通过您目前的相同方式启动服务。

其次,在您的服务实现中,发送广播消息以指示您已完成而不是尝试使用BoundService要容易得多。因此,在你的服务,你会做这样的事情:

Intent intent = new Intent(); // specify the intent filter appropriately here 
sendBroadcast(intent); 

然后,在你的活动,你会要注册,将被通知这些变化BroadcastReciever。有关更多详细信息,请参阅BroadcastReceiver doc

+0

感谢分享诺埃尔!我要给它一个镜头并回报。 – KellyTheDev

相关问题