【问题标题】:Informing activity class about action from service or thread class通知活动类有关来自服务或线程类的操作
【发布时间】:2013-11-08 04:39:18
【问题描述】:

在我的服务类中,我正在启动一个线程。如果线程类采取任何行动,通知活动的最佳方式是什么?我想通知我的活动类线程已经采取了一些行动。从下面的代码中可以清楚问题

MyService 类 onCreate() 方法

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

    if (downloadThread == null) {
        downloadThread = new DownloadThread(this);
        downloadThread.activateUserSession();
        downloadThread.start();
    }
}

我的下载线程

public void run()
{
    while (!isStopRequested) {
        if (isSessionActive && downloadNow) 
        {

            downloadNow = false;
            informActivity("Download Started");

            //do some loading work !!
            SystemClock.sleep(10000);

            informActivity("Download Finished");
        }

        SystemClock.sleep(2000);
    }
}

当 downloadNow 为 true 等时不要详细说明。我只需要如何通知我的活动下载开始和下载完成。处理程序需要做一些事情。谁能告诉我处理这种情况的最佳方法。

【问题讨论】:

  • 您是使用 Intent 启动服务还是绑定到它? (您应该具有约束力。)
  • 我正在通过意图从 Application 类启动我的服务并将服务绑定到我称之为 MainActivity 的活动
  • 我不确定最佳解决方案,但您可以使用处理程序来达到您的目的。
  • 是的,我知道,我什至在我的问题中添加了这个。但是如何在我的服务和/或服务类中使用该处理程序来通知我有关事件的活动
  • 查看这个例子Bluetooth Chat

标签: android android-service android-handler


【解决方案1】:

我建议您使用后台服务中的startActivity。因此,以最简单的形式,您可以拥有

String theEvent = "downloadStarted";
Intent intentForActivity = new Intent(this, MyActivity.class);
intentForActivity.putExtra(THE_EVENT, theEvent);
startActivity(intentForActivity)

如果您的活动已经在运行(如您所描述的),那么入口点将是onNewIntent,您可以在那里拉出THE_EVENT 并逐案处理

onNewIntent(Intent intent) {
    String theEvent = intent.getExtra(THE_EVENT);
    if (theEvent.equals("downloadStarted") {
        // do your stuff
    } else if (theEvent.equals("downloadCompleted") {
        // do your other stuff 
    }
}

Handler 仅允许您将事情排队以备后用,而不会完全阻塞您的线程。在您的情况下,如果您正在谈论大量并发下载,这可能会有所帮助,但不必开始。

【讨论】:

  • 感谢 scott 的回答,但我已经开始了我的申请。我的活动处于运行模式。我可以这么说,假设在该活动中,当我单击一个按钮时,它会检查一些条件,然后从服务启动 DownloadThread。因此,当下载开始时,我想通知我的活动下载开始,并在完成时相应通知。
  • 不要被名字所迷惑:它被称为startActivity,但它的作用是向正在运行的活动发送消息。然后,Activity 将执行一个名为 onNewIntent 的函数,而不是 onCreate
  • 好的,明白了。当我可能需要将相同的东西也用于其他目的时,我仍然不明白将意图发送到硬编码的活动名称。处理程序是专用于接听电话的东西。因此,最好使用专用于特定目的的东西。如果它工作正常,仍然会以这种方式测试。
  • 是的,所以更笼统地说,您将使用sendBroadcast 而不是startActivity,并为您的活动实现BroadcastReceiver。这将使用IntentFilter 来挑选广播,例如具有特定的操作或类别。
【解决方案2】:

首先,您不需要使用 Intent 绑定来启动 Service。一个或另一个就足够了。

在这种情况下,我建议绑定到服务,因为这使您有机会通过处理程序和信使建立通信。您可以使用 ServiceConnection 类的 onServiceConnected 方法来获取 Service 中定义的 Messenger。有关如何执行此操作的示例,请参阅创建绑定服务下的 Android docs here。在他们的示例中,它们返回对 Service 实例的引用,但您应该将其替换为对 Messenger 或 Handler 的引用。一旦在 Activity 和 Service 中都有一个 Handler/Messenger,来回通信应该是微不足道的。请注意,如果您将 Handler 放在后台 Thread 中,您可能需要在 Thread 的构造函数中调用 Looper.prepare()。

【讨论】:

  • 嘿thanx 回答。任何演示或代码 sn-p 都会有所帮助,用于演示工作。
  • 嘿,我看到了你的代码,但我想这个方法会从我的服务类返回消息,但我需要服务实例,因为还有其他几个过程是通过服务完成的。有没有办法让我们在我的活动类中同时获得实例
  • 在文档示例中,它获取了一个服务实例。你可以在 Service 中定义方法来获得你想要的任何东西。在我看来,您只需要与 Thread 进行通信,因此我建议您只需设置与 Handler 或 Messenger 的通信即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 2011-05-05
  • 1970-01-01
  • 2011-06-03
  • 2012-02-04
  • 1970-01-01
相关资源
最近更新 更多