2011-03-28 8 views
1

저는 안드로이드 장치에서 서버로 소켓을 사용하여 데이터를 보내고 역순으로 데이터를 보내고 응용할 것입니다. AsyncTask 클래스를 사용하여 연결을 처리하고 있습니다. 내 문제는 내 주요 활동 클래스의 일부 지점에서 내가 입력 스트림에서 예를 들어 읽을 수있다.AsyncTask, Android를 사용하는 동안 스레드를 동기화 할 때 문제가 발생했습니다.

conhandler = new ConnectionHandler(); 
    conhandler.execute(); 
    Log.i("AppOne", "Reading from stream"); 
    message = conhandler.readFromStream(); 

는 어떤 일이 내 ConnectionHandler 클래스는 소켓 연결을 설정하기 전에이 코드가 실행된다는 점이다. 이 문제를 해결할 수있는 방법은 무엇입니까? 가 여기 내 ConnectionHandler 클래스에 코드입니다 :

public class ConnectionHandler extends AsyncTask<Void, Void, Void>{ 

public static String serverip = "192.168.1.100"; 
public static int serverport = 7777; 
Socket s; 
public DataInputStream dis = null; 
public DataOutputStream dos = null; 
public int message; 



@Override 
protected Void doInBackground(Void... params) { 

    try { 
     Log.i("AsyncTank", "doInBackgoung: Creating Socket"); 
     s = new Socket("192.168.1.100", 7777); 
    } catch (Exception e) { 
     Log.i("AsyncTank", "doInBackgoung: Cannot create Socket"); 
    } 
    Log.i("AsyncTank", "doInBackgoung: Socket created"); 
    if (s.isConnected()) { 
     try { 
      Log.i("AsyncTank", "doInBackgoung: inside input try"); 
      dis = new DataInputStream(s.getInputStream()); 
      Log.i("AsyncTank", "doInBackgoung: InputStream assigned"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected"); 
      e.printStackTrace(); 
     } 
     try { 
      Log.i("AsyncTank", "doInBackgoung: inside output try"); 
      dos = new DataOutputStream(s.getOutputStream()); 
      Log.i("AsyncTank", "doInBackgoung: OutputStream assigned"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected"); 
      e.printStackTrace(); 
     } 
    } else { 
     Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket is closed"); 
    } 

    return null; 
} 

public void writeToStream(double lat, double lon) { 
    try { 
      Log.i("AsynkTask", "writeToStream : Writing lat"); 
      dos.writeDouble(lat); 
      dos.flush(); 
     } catch (Exception e) { 
     Log.i("AsynkTask", "writeToStream : Writing failed"); 
    } 
    try { 
      Log.i("AsynkTask", "writeToStream : Writing lon"); 
      dos.writeDouble(lon); 
      dos.flush(); 
     } catch (Exception e) { 
     Log.i("AsynkTask", "writeToStream : Writing failed"); 
    } 
} 

public int readFromStream() { 
    try { 
     if (s.isConnected()) { 
      Log.i("AsynkTask", "readFromStream : Reading message"); 
      message = dis.readInt(); 
     } else { 
      Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed"); 
     } 
    } catch (Exception e) { 
     Log.i("AsynkTask", "readFromStream : Reading failed"); 
    } 
    return message; 
} 

}

+2

을 접속의 확립 후에, doInBackground 메소드의 스트림로부터 읽어들입니다. –

답변

2

그래, 당신은 ASyncTask 스레드에서 모든 네트워크 운영 할 필요가있다. onPostExecute() 메서드를 재정 의하여 작업이 끝나면 작업을 수행 할 수도 있습니다. 거기 물건은 UI 스레드에서 실행됩니다, 그래서 당신은 textviews를 조작 할 수있는 등 레이아웃

당신이 그것을에 두 번 소켓을 열고 쓰기 위해 AsyncTask를 사용할 수 방법

예 :가이

public class ASyncExample extends Activity { 

    private TextView mTextView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // set stuff up 
     super.onCreate(savedInstanceState); 
    } 

    private class WriteToServer extends AsyncTask<Double, Void, Void> { 

     private final String serverip = "192.168.1.100"; 
     private final int serverport = 7777; 
     Socket s; 
     private DataOutputStream dos = null; 

     @Override 
     protected Void doInBackground(Double... params) { 

      try { 

       // open the stream 
       s = new Socket("192.168.1.100", 7777); 
       dos = new DataOutputStream(s.getOutputStream()); 

       // write the passed double to the stream 
       dos.writeDouble(params[0]); 
       dos.flush(); 

      } catch (Exception e) { 
       Log.i("AsyncTank", "something's gone wrong"); 
      } 

      return null; 
     } 
    } 
} 
+0

그래서 내 doInBackground() 및 "통신"물건 onPostExecute() 또는 적어도 독서 부분에있는 모든 과제를 수행해야합니까? 어떻게 내가 onPostExecute()에서 읽은 것을 주요 Activity 클래스로 전달할 수 있습니까? – Syllkons

+0

아니요 - doInBackground의 모든 내용이 다른 스레드에서 발생하므로 UI ​​속도가 느려지지 않습니다. 그러니 그 부분에 할 수있는 모든 것을 넣으십시오. 'onPostExecute'는 메인 (UI) 쓰레드에서 돌아가며, 작업이 끝나면 UI 요소를 업데이트하고자 할 때만 사용해야합니다. 메인 액티비티와 통신하는 가장 쉬운 방법은 위와 같이 'ASyncTask'의 하위 클래스를 내부 클래스 또는 액티비티로 만드는 것입니다. 그렇게하면 위의 예제에서'mTextView'와 같은 클래스 필드에 접근 할 수 있습니다. –

+0

나는 그것을 알고 있다고 생각한다, 나는 그것을 내일 시도하고 내가 무엇을 생각해 낼지를 볼 것이다. – Syllkons

관련 문제