I am trying to create a service that manages my network communication on my app but everytime I destroy my activity my server crashes and I believe this is I am still waiting to receive on the server end.
My understanding of the service is it runs until you stop it so I feel my channel should be open until I close. I know it'd take a lot of battery life but, I'm trying to understand the concept of the service very well before I optimize my battery life. Here is what I have
public class SampleService extends Service {
public final static String TAG = SampleService.class.getName();
private HandlerThread nThread;
private NetworkHandler nHandler;
private Looper nLooper;
private Socket socket;
private ObjectInputStream is;
private ObjectOutputStream os;
.......
.........
@Override
public void onCreate()
{
Log.i(TAG, "onCreate(); Sample Created");
new Thread(new Runnable()
{
@Override
public void run() {
// TODO Auto-generated method stub
try {
socket = new Socket("192.168.1.185", 6060);
os = new ObjectOutputStream(new DataOutputStream(socket.getOutputStream()));
is = new ObjectInputStream(new DataInputStream(socket.getInputStream()));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
Log.e(TAG, "onCreate(): UnknownHostException error", e);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(TAG, "onCreate(): IOException error", e);
}
}
}).start();
nThread = new HandlerThread("Network Thread", Process.THREAD_PRIORITY_BACKGROUND);
nThread.start();
nLooper = nThread.getLooper();
nHandler = new NetworkHandler(nLooper);
Log.i(TAG, "onCreate(); Service setup");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service started "+ startId, Toast.LENGTH_SHORT).show();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
@Override
public void onDestroy() {
Toast.makeText(this,"Service Destroyed", Toast.LENGTH_SHORT).show();
Log.i(TAG, "onCreate(); Sample Destroyed");
}
And Activity
public class ServiceActivity extends Activity {
Intent service;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
service = new Intent(this, SampleService.class);
startService(service);
}
........
........
}
I don't really have much added there just this...
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_service, menu);
return true;
}
@Override
public void onPause()
{
super.onPause();
// stopService(service);
}
I decided to add my server to make things clear...
public class CloudServer{
private ServerSocket serverSocket;
private List<Socket>clientSockets;
public static final String TAG = CloudServer.class.getName();
public CloudServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
clientSockets = new ArrayList<Socket>();
System.out.println("Listening to clients on port "+ port);
for(;;) // infinite loop
{
Socket s;
String id = generateSessionId();
clientSockets.add(s = serverSocket.accept());
System.out.println("Connection was established");
if(sessionId.size() > 0)
{
Set<String>ids = sessionId.keySet();
for(String session: ids)
{
while(id.equals(session))
id = generateSessionId();
}
}
sessionId.put(id, s);
new Thread(new Worker(s, id)).start();
}
........
}
public static void main(String [] args) throws IOException, ClassNotFoundException, SQLException
{
new CloudServer(6060);
}
.........
}
這裏後,工作人員,因爲在一段時間(的服務器安卓::保持網絡連接活着破壞活動
package com.dcloud.server.service;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Worker implements Runnable{
private Socket socket;
private ObjectInputStream is;
private ObjectOutputStream os;
private boolean running;
public static final String TAG = Worker.class.getName();
private Message in;
private String sessionId;
public Worker(Socket s, String id) throws IOException
{
this.socket = s;
os = new ObjectOutputStream(socket.getOutputStream());
is = new ObjectInputStream(socket.getInputStream());
sessionId = id;
running = true;
}
public String getSessionId()
{
return sessionId;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(running)
{
try {
while((in = (Message) is.readObject())!= null){
if(in.getRequest() == Event.Request.REGISTER)
{
//debugging purposes
CloudServer.writeToFile(TAG + ": got into the Register request");
new Thread(new Runnable()
{
@Override
public void run() {
// TODO Auto-generated method stub
try {
String message = in.getMessage();
registerUser(message);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
else if(in.getRequest() == Event.Request.LOGIN)
{
CloudServer.writeToFile(TAG + ": got into the login request");
new Thread(new Runnable()
{
@Override
public void run() {
// TODO Auto-generated method stub
try {
String message = in.getMessage();
handleLogin(message);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
else if(in.getRequest() == Event.Request.DISCONNECT)
{
running = false;
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
is.close();
os.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
........
.......
// I don't think this affects anything...
}
我得到和IO異常及(在= is.readObject)! = null) 這表明我的應用正在試圖破壞連接時,我摧毀了活動。這就是我如何解釋,但根據Android的網站上的服務文檔,服務應該是活的,直到我停止它明確自己...
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.dcloud.server.service.Worker.run(Worker.java:56)
at java.lang.Thread.run(Unknown Source)
你有什麼其他的代碼在你的'Activity'中?例如'onPause()','onStop()','onDestroy()'? – Squonk
我沒有真正實現它們...我把其餘的代碼 – legend
確定好,所以你的'onPause()'方法有'stopService(service);'註釋掉了。你是否說過,即使它評論說你的「服務」仍在終止? – Squonk