使用Android服务处理网络连接

时间:2011-04-21 01:09:35

标签: java android android-service android-networking

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

3 个答案:

答案 0 :(得分:8)

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

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

public interface ServerResponseHandler {

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

}

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

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

答案 1 :(得分:0)

您是否查看了服务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

答案 2 :(得分:0)

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

使用广播接收器时,您仍然必须在销毁活动时取消注册,但是服务永远不会直接引用活动,因此如果您忘记活动将不会泄露。在创建主题时,让活动寄存器更容易收听主题,因为它永远不必获得对服务的直接引用...

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