我正在尝试启动service
,然后打开socket
以与服务器建立连接。
点击按钮,我创建新的Thread
,然后开始服务。
Thread t = new Thread(){
public void run(){
mIntent= new Intent(MainActivity.this, ConnectonService.class);
mIntent.putExtra("KEY1", "Value used by the service");
context.startService(mIntent);
}
};
t.start();
然后在service
上,我尝试打开socket
并与服务器连接
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
Scanner scanner = new Scanner(socket.getInputStream());
message = scanner.nextLine();
} catch (IOException e) {
e.printStackTrace();
}
return Service.START_NOT_STICKY;
}
但是当我打电话时,我有错误
08-30 08:56:49.268: E/AndroidRuntime(3751): java.lang.RuntimeException: Unable to start service com.example.testofconnection.ConnectonService@40ef02a8 with Intent { cmp=com.example.testofconnection/.ConnectonService (has extras) }: android.os.NetworkOnMainThreadException*
我认为问题是service
在main thread
上,但我无法找到如何在新的(独立)主题上开始服务以保留connection alive
?
答案 0 :(得分:12)
您可以使用IntentService。只需使用主线程中的Intent正常启动它。 onHandleIntent()
方法在后台线程中执行。把你的套接字代码放在那里。这是一个示例代码。
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
// this method is called in background thread
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
在您的活动中,您可以按照以下方式启动服务。
startService(new Intent(this, MyIntentService.class));
如果您需要持久的服务,您可以创建一个正常的服务并在那里开始一个线程。这是一个例子。确保将其作为“前台”服务启动。这将使服务运行更长时间而不会被Android杀死。
public class MyAsyncService extends Service {
private AtomicBoolean working = new AtomicBoolean(true)
private Runnable runnable = new Runnable() {
@Override
public void run() {
while(working.get()) {
// put your socket-code here
...
}
}
}
@Override
public void onCreate() {
// start new thread and you your work there
new Thread(runnable).start();
// prepare a notification for user and start service foreground
Notification notification = ...
// this will ensure your service won't be killed by Android
startForeground(R.id.notification, notification);
}
@Override
public onDestroy() {
working.set(false)
}
}
答案 1 :(得分:4)
将此代码移至您的主题:
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
Scanner scanner = new Scanner(socket.getInputStream());
message = scanner.nextLine();
} catch (IOException e) {
e.printStackTrace();
}
就像一个例子(我不确定这适合你的任务):
Thread t = new Thread(){
public void run(){
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
Scanner scanner = new Scanner(socket.getInputStream());
message = scanner.nextLine();
} catch (IOException e) {
e.printStackTrace();
}
mIntent= new Intent(MainActivity.this, ConnectonService.class);
mIntent.putExtra("KEY1", "Value used by the service");
context.startService(mIntent);
}
};
t.start();
您应该知道UI线程上正在运行服务,因此您收到此错误。有关Android中各种线程方法的详细信息,请查看this nice site。