2012-12-10 130 views
0
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) 
+0

你有什麼其他的代碼在你的'Activity'中?例如'onPause()','onStop()','onDestroy()'? – Squonk

+0

我沒有真正實現它們...我把其餘的代碼 – legend

+0

確定好,所以你的'onPause()'方法有'stopService(service);'註釋掉了。你是否說過,即使它評論說你的「服務」仍在終止? – Squonk

回答

0

如果你的手機進入休眠狀態(屏幕變暗),你贏了沒有網絡連接。如果你想保持連接,你需要通過獲取一個WakeLock來防止手機進入睡眠狀態。這當然會帶來使用電池的損失,所以您應該在完成網絡操作後立即將其釋放。

+0

好吧。謝謝,我猜這是摧毀一項活動的同樣心態? – legend

+0

銷燬活動並不一定會阻止互聯網連接。但是,如果您不與其進行交互,手機最終會進入睡眠狀態,連接將被切斷。 –

+0

是的,但在我的情況下,手機不會入睡。我所做的就是銷燬活動,並在服務器中收到運行時錯誤.... – legend