当前位置: 首页 > 面试题库 >

从服务到活动的线程获取处理程序

邴越彬
2023-03-14
问题内容

情况:

  1. 活动绑定到已启动的前台服务。
  2. 服务将本地活页夹分发给活动。
  3. 活动通过getService()调用获取对服务的引用。
  4. 活动希望使用消息 直接 与服务中运行的线程进行通信。它从活动中调用mService.getThreadHandler()方法。

问题:

  • 如何从当前正在运行的线程中将Handler放入活动活动中,以便可以将消息直接发布到线程的messagequeue中?

我不需要在服务中使用Messenger,我想从活动端直接与服务中的线程通信。

编辑: 通过调用 如下代码 ,活动获取服务中线程本身的处理程序:

活动代码:

Handler mServiceThreadHandler;
ServiceConnection mServiceConnection;

public void onStart() {
  if (!bindService(new Intent(this, MainService.class), mServiceConnection,    Context.BIND_AUTO_CREATE)) 
  {
    Log.e(TAG, "Client did not bind to Service!");
  } 
  super.onStart();
}

public class MyLocalServiceConnection implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        mService = (MainService) binder.getService();
                    // the handler of the service is actually a handler of a thread
                    // within the service, and is set automatically within the binding
                    // activity when binding to the service. That way you have a direct
                    // "connection" with the message queue of the thread instead of
                    // a message queue in the service itself (main thread of service)
        mServiceThreadHandler = mService.getServiceHandler();

        if (mServiceThreadHandler == null) {
            Log.e(TAG, "Service handler is NULL");
        }
        mBoundedToService = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mServiceThreadHandler = null;
        mBoundedToService = false;
    }
}

服务代码:

private HandlerThread mServiceThread = new MyServiceThread();

public Handler getServiceHandler() {
    return new Handler(mServiceThread.getLooper());
}

是否执行 新的Handler(mServiceThread.getLooper());
返回一个新的处理程序或mServiceThread中的相同处理程序?

编辑2: 使用接收消息的serviceThread更新服务代码

public class MyService extends Service {
  private MyHandlerThread serviceThread = new MyHandlerThread("serviceThread");

  serviceThread.start();

public Handler getServiceHandler() {
  // hand out the same handler of the service thread for using it in an activity!
  // serviceThread.getLooper() is the current looper of the thread
  // serviceThread is the 'this' which handles the messages (see MyHandlerThread)
  return new Handler(serviceThread.getLooper(), serviceThread); 
}

  // do stuff in Service
}

public class MyHandlerThread extends HandlerThread implements android.os.Handler.Callback {
public MyHandlerThread(String name) {
    super(name);
}
public MyHandlerThread(String name, int priority) {
    super(name, priority);
}
@Override
public boolean handleMessage(Message msg) {
    // TODO define your own message handling here.
    return false;
}
}

正确?


问题答案:

试试这个(我用Activity来测试它,您将使用Service):

protected void onCreate(Bundle savedInstanceState) {
    ht = new HandlerThread("HT");
    ht.start();
    htHandler = new Handler(ht.getLooper(), htCallback);
    mainHandler = new Handler(mainCallback);
    for (int i = 0; i < 10; i++) {
        htHandler.sendMessageDelayed(htHandler.obtainMessage(99, i, 0), i * 3000);
    }
}

private HandlerThread ht;
private Handler htHandler;
private Handler mainHandler;

private Callback htCallback = new Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        Log.d(TAG, "handleMessage **********************");
        Log.d(TAG, "handleMessage " + msg);
        Log.d(TAG, "handleMessage Thread: " + Thread.currentThread());
        if (msg.arg1 == 4) {
            Log.d(TAG, "handleMessage sending back to Main thread");
            mainHandler.sendEmptyMessage(101);
        }
        return false;
    }
};

private Callback mainCallback = new Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        Log.d(TAG, "handleMessage ########################");
        Log.d(TAG, "handleMessage " + msg);
        Log.d(TAG, "handleMessage Thread: " + Thread.currentThread());
        Log.d(TAG, "handleMessage i'm quitting");
        ht.quit();
        return false;
    }
};


 类似资料:
  • 在我的Spring批处理配置中,我试图设置一个分区步骤,该步骤访问JobParameters中的值,如下所示: 我已经向SpringBoot应用程序添加了@EnableBatchProcessing注释。 异常堆栈如下所示 2018-05-25 21:07:32,075 ERROR[main]org.springframework.batch.core.job.abstractJob:执行作业or

  • 我们的生产服务器(apache-tomcat-7.0.6)出现了这个问题,它正在运行一个使用MySQL作为DB的Spring JPA Hibernate应用程序。在这个问题中,服务器速度变慢,一分钟内就会失去响应,活动的tomcat线程数达到200个(我们使用javamelody观察这些情况)。日志看起来像: 事务的创建一直持续到服务器达到200个线程(需要1-2分钟)并没有响应为止。在此期间,我

  • 问题内容: 我有一个固定的线程池,我可以将任务提交给该线程池(限制为 5个 线程)。如何找出这 5个 线程中的哪一个执行我的任务(例如“第3 个 线程中的第3 个 线程正在执行此任务”)? 问题答案: 使用:

  • 问题内容: 代码如下所示: 有没有一种方法可以通过发起类来获取活动线程的数量? 问题答案: 这是对Doug Hellman的多处理ActivePool示例代码(使用线程)的较小修改。这个想法是让您的工作人员在一个池中注册自己,使用线程锁来协调他们对活动目录的修改: 产量

  • 问题内容: 在大多数应用程序服务器上,J2EE Ejb规范禁止“手动”创建线程,因为这些资源应由服务器管理。 但是有什么方法可以从Tomcat,Glassfish,Jboss等获取线程;因此访问他们的ThreadPool? 问题答案: 您可以使用commonj WorkManager 。IBM和BEA提出了一项建议,以提供一种完成此任务的标准方法(访问容器管理的线程)。 尽管它没有包含在实际规范中

  • 如果有人能分享他解决以下问题的经验,我将不胜感激。我在JDK实现中有一个SOAP服务(我相信这就是Metro)。 出于日志记录的目的,我们需要提取传入请求和生成响应的正文。我试图通过在服务器端实现SOAPHandler来获取它。我将处理程序配置为Spring bean。我找到的所有示例基本上都复制了Oracle留档:https://docs.oracle.com/cd/E23943_01/web.