从已经运行的粘性服务中发送数据到活动。

问题描述 投票:0回答:2

我创建了粘性后台服务,应该在启动时启动。

public class AutostartReceiver extends BroadcastReceiver
{
    public AutostartReceiver()
    {
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        context.startService(new Intent(context, MyService.class));
    }
}

我的服务是为了在后台做一些工作,它通过创建线程来实现。另外,还有一个Messenger类用于向我的主活动发送工作状态。

@Override
  public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.i(TAG, "Service onStartCommand " + startId);

        final int currentId = startId;

        Messenger callback = null;
        if(intent!=null)
        {
            callback = intent.getParcelableExtra("messenger");
        }


        final Messenger finalCallback = callback;
        Runnable r = new Runnable()
        {
            public void run()
            {
                ... do something, then stop

                stopSelf();
            }
        };




        if(t == null)
        {
            t = new Thread(r);
            t.start();
        }


        return Service.START_STICKY;
    }

主活动接收在我的服务中运行的后台线程发送的消息(一些命令,服务定期发送。

Handler mHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case 0:
                    Toast.makeText(MainActivity.this,"Service runing", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    };

只有当我从活动中启动我的服务,并使用活动的上下文时,这才有效。显然,如果服务在启动时被启动,或者我的应用被关闭(从最后一个应用列表中移除),然后又被打开,我的活动就不能再从服务中获取任何消息。

如果我在服务已经运行的时候调用启动服务,它就会简单地运行。OnStartCommand 所以要么创建新的线程(我不希望这样),要么我需要销毁正在运行的线程,然后重新运行线程。

有什么方法可以让我的活动从服务中接收消息,而不实际接触到里面已经运行的线程?我知道绑定服务,但我不清楚如何在我的具体情况下使用它们。

java android multithreading service messenger
2个回答
3
投票

作为替代方式,你可以使用 本地广播管理器 发送数据从 ServiceActivity.

从服务中广播您的信息。

private void broadcastMessage(Context context){
     Intent intent = new Intent("UI_UPDATE_BROADCAST");
     intent.putExtra("MESSAGE", "MyMessage");
     LocalBroadcastManager.getInstance(context).sendBroadcast(intent);        
} 

在您的活动中注册广播接收器来接收信息。

@Override
public void onResume() {
    super.onResume();
    LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver, new IntentFilter("UI_UPDATE_BROADCAST"));
}


@Override
public void onPause() {
     super.onPause();
     LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mMessageReceiver);
}

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
         //Do Something With Received Data
         String msg = intent.getStringExtra("MESSAGE");
     }
}; 

1
投票

我会用广播接收器来接收 Service-至Activity 通信。

代码。

public class MyActivity extends Activity {
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //Toast here
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("message-name"));
        }
      @Override
        public void onDestroy() {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);

            super.onDestroy();
        }
}

然后在你的服务中,你会广播这样的消息。

Intent intent = new Intent("message-name");
intent.putExtra("data", 1);

LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
© www.soinside.com 2019 - 2024. All rights reserved.