[英]How to run service not on main thread?
我正在嘗試啟動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
?
您可以使用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)
}
}
將此代碼移動到您的主題:
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中各種線程方法的更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.