用于 TCP 套接字的 Android 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3619372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android service for TCP Sockets
提问by Kyle
Based on a suggestion in a previous question I asked on here, I'm trying to push my socket connection for an application that I've written into a service. I spent the better part of the day yesterday researching services and actually mocked up a few (one remote, one local).
根据我在这里提出的上一个问题中的建议,我正在尝试为已写入服务的应用程序推送我的套接字连接。我昨天大部分时间都在研究服务,实际上模拟了一些(一个远程的,一个本地的)。
My question is in two parts:
我的问题分为两部分:
1) after having played with both a local service and a remote service, I'm still not sure as to which one would be best for my situation. This is due in large part to the fact that I guess I still don't quite understand what advantages running in another 'process' is going to give me. I'm spawning a new thread for the socket connection no matter what so I won't have any thread contention with the UI. So what does putting the service in another process enable me to do? Will I potentially see better performance that way? My limited understanding is that by putting it in a different process, the service will run independently of whatever activity I have running on my app. I do have a few different activities, but only one of them requires the socket connection which I will rebuild everytime that activity is opened anyway. So would a local service be the way to go for me?
1) 在玩过本地服务和远程服务之后,我仍然不确定哪一个最适合我的情况。这在很大程度上是因为我想我仍然不太明白在另一个“进程”中运行会给我带来什么好处。无论如何,我都会为套接字连接生成一个新线程,因此我不会与 UI 发生任何线程争用。那么,将服务放入另一个进程中能让我做什么?我可能会以这种方式看到更好的性能吗?我有限的理解是,通过将它放在不同的进程中,该服务将独立于我在我的应用程序上运行的任何活动而运行。我确实有一些不同的活动,但其中只有一个需要套接字连接,无论如何我都会在每次打开该活动时重建该连接。
2) I'm going to have my socket "listener" (DataInputStream().readLine() inside a while loop) inside my service for any new data that gets passed down from the server. After the playing I did yesterday, I could not figure out how to pass the data that it reads to the actual "client" (either bound client by remote service, or local client itself) in "realtime".
2)我将在我的服务中使用我的套接字“侦听器”(DataInputStream().readLine() 在 while 循环中),用于从服务器传递下来的任何新数据。昨天玩完之后,我不知道如何“实时”将它读取的数据传递给实际的“客户端”(远程服务绑定的客户端,或本地客户端本身)。
Would greatly appreciate some suggestions for part 1, and some help with part 2 (code examples? :))
非常感谢第 1 部分的一些建议,以及第 2 部分的一些帮助(代码示例?:))
TIA
TIA
Edit: added code of my service - going with local service
编辑:添加了我的服务代码 - 使用本地服务
Service Class:
服务等级:
public class SocketService extends Service {
Socket s;
PrintStream os;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return myBinder;
}
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
public SocketService getService() {
return SocketService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
s = new Socket();
}
public void IsBoundable(){
Toast.makeText(this,"I bind like butter", Toast.LENGTH_LONG).show();
}
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show();
Runnable connect = new connectSocket();
new Thread(connect).start();
}
class connectSocket implements Runnable {
@Override
public void run() {
SocketAddress socketAddress = new InetSocketAddress("192.168.1.104", 4505);
try {
s.connect(socketAddress);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s = null;
}
}
Activity that calls service:
调用服务的活动:
public class SocketServiceController extends Activity {
private SocketService mBoundService;
private Boolean mIsBound;
public SocketServiceController ssc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ssc = this;
setContentView(R.layout.main);
Button start = (Button)findViewById(R.id.serviceButton);
Button stop = (Button)findViewById(R.id.cancelButton);
start.setOnClickListener(startListener);
stop.setOnClickListener(stopListener);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((SocketService.LocalBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
private void doBindService() {
bindService(new Intent(SocketServiceController.this, SocketService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
mBoundService.IsBoundable();
}
private void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
private OnClickListener startListener = new OnClickListener() {
public void onClick(View v){
startService(new Intent(SocketServiceController.this,SocketService.class));
doBindService();
}
};
private OnClickListener stopListener = new OnClickListener() {
public void onClick(View v){
stopService(new Intent(SocketServiceController.this,SocketService.class));
}
};
}
回答by CommonsWare
This is due in large part to the fact that I guess I still don't quite understand what advantages running in another 'process' is going to give me.
这在很大程度上是因为我想我仍然不太明白在另一个“进程”中运行会给我带来什么好处。
Generally, none. You create a remote service if you are expecting other applications to communicate with the service. If it will only be used by your own application, use a local service.
一般来说,没有。如果您希望其他应用程序与该服务进行通信,则可以创建一个远程服务。如果它只会被您自己的应用程序使用,请使用本地服务。
Also, a remote service has nothing to do with creating a separate process within your application.
此外,远程服务与在应用程序中创建单独的进程无关。
Will I potentially see better performance that way?
我可能会以这种方式看到更好的性能吗?
You will see worse performance that way, due to extra memory consumption.
由于额外的内存消耗,您会看到更差的性能。
My limited understanding is that by putting it in a different process, the service will run independently of whatever activity I have running on my app.
我有限的理解是,通过将它放在不同的进程中,该服务将独立于我在我的应用程序上运行的任何活动而运行。
Services have a lifecycle independent from activities regardless of whether it is local or remote.
服务具有独立于活动的生命周期,无论它是本地的还是远程的。
So would a local service be the way to go for me?
那么本地服务是否适合我?
Sounds likely.
听起来很有可能。
After the playing I did yesterday, I could not figure out how to pass the data that it reads to the actual "client" (either bound client by remote service, or local client itself) in "realtime".
昨天玩完之后,我不知道如何“实时”将它读取的数据传递给实际的“客户端”(远程服务绑定的客户端,或本地客户端本身)。
Use the local binding pattern, and have the activity call an API on the service to register (and unregister) an event listener. Have the service pass the data to the activity via the listener.
使用本地绑定模式,让活动调用服务上的 API 来注册(和取消注册)事件侦听器。让服务通过侦听器将数据传递给活动。