【问题标题】:Using an Android Service to handle a network connection使用 Android 服务处理网络连接
【发布时间】:2011-04-21 01:09:35
【问题描述】:

我正在开发一个需要与聊天服务器保持网络连接的 Android 应用。我知道我可以创建一个服务来启动与服务器的连接,但是该服务如何通知 Android Activity 新的传入消息? Activity 需要更新视图以显示新消息。我对 Android 还很陌生,所以任何帮助表示赞赏。谢谢!

【问题讨论】:

    标签: java android android-service android-networking


    【解决方案1】:

    您可以将处理程序传递给您的服务吗?

    首先,将您的处理程序定义为接口。这是一个例子,所以你的可能更复杂。

    public interface ServerResponseHandler {
    
        public void success(Message[] msgs); // msgs may be null if no new messages
        public void error();
    
    }
    

    在您的活动中定义处理程序的实例。由于它是一个接口,您将在 Activity 的此处提供实现,因此您可以从处理程序中引用封闭 Activity 的字段和方法。

    public class YourActivity extends Activity {
    
    // ... class implementation here ...
    
        updateUI() { 
            // TODO: UI update work here
        }
    
        ServerResponseHandler callback = new ServerResponseHandler() {
    
            @Override
            public void success(Message[] msgs) {
                // TODO: update UI with messages from msgs[]
    
                YourActivity.this.updateUI();
            }
    
            @Override
            public void error() { 
                // TODO: show error dialog here? (or handle error differently)
            }
    
        }
    
        void onCheckForMessages() { 
            networkService.checkForMessages(callback);
        }
    

    并且 NetworkService 将包含类似的内容:

    void checkForMessages(ServerResponseHandler callback) { 
    
        // TODO: contact server, check for new messages here
    
        // call back to UI
        if (successful) { 
            callback.success(msgs);
        } else {
            callback.error();
        }
    }  
    

    此外,正如 Aleadam 所说,您还应该远离默认情况下服务在同一线程上运行的情况。对于网络之类的东西,这通常不是首选行为。 Android Fundamentals Page on Services 明确警告不要在没有单独线程的情况下联网:

    注意:服务在其托管进程的主线程中运行——该服务不 创建自己的线程并且不在单独的进程中运行(除非您指定 否则)。这意味着,如果您的服务将执行任何 CPU 密集型工作或 阻塞操作(例如 MP3 播放或联网),您应该创建一个新线程 在服务内完成这项工作。通过使用单独的线程,您将减少 应用程序无响应 (ANR) 错误的风险,并且应用程序的主线程可以保持专用于用户与您的活动的交互。

    有关在服务中使用线程的更多信息,请查看 SO 文章 Application threads vs Service threadsHow to start service in new thread in android

    【讨论】:

      【解决方案2】:

      您是否查看过服务 API 页面:http://developer.android.com/reference/android/app/Service.html
      它有几个关于如何与服务交互的示例。

      服务与Activity运行在同一个线程和同一个Context上。也可以在这里查看:http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29

      最后,再看看 Lars Vogel 的文章:http://www.vogella.de/articles/AndroidServices/article.html

      【讨论】:

        【解决方案3】:

        一种常见且有用的方法是在您的 Activity 中注册一个广播接收器,并让 Service 在它有有用数据时发送通知事件。我发现这比通过回调实现处理程序更容易管理,主要是因为它在配置更改时更容易和更安全。如果您将直接的 Activity 引用传递给 Service,那么您必须非常小心地在 Activity 被销毁时(在旋转或后台处理期间)清除它,否则会出现泄漏。

        使用广播接收器时,您仍然需要在 Activity 被销毁时取消注册,但是 Service 永远不会直接引用 Activity,因此如果您忘记了 Activity 也不会泄露。在创建时让 Activity 注册来监听主题也更容易,因为它永远不必直接获取对服务的引用......

        Lars Vogel 的文章讨论了这种方法,绝对值得一读! http://www.vogella.com/tutorials/AndroidServices/article.html#using-receiver

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-14
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 2014-10-10
          • 1970-01-01
          • 2020-04-28
          • 2013-11-18
          相关资源
          最近更新 更多