day04 네트워크 프로그래밍 (1)

네트워크 이미지 뷰어

  • 이미지 주소 지정
  • http 요청 발송
    URL url = new URL(address);
    // , 
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    // 
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    // , 
    conn.setRequestMethod("GET");
    // , get 
    //conn.connect();
    // , ,200 
    conn.getResponseCode();
    
  • 서버의 그림은 흐르는 형식으로 브라우저에 되돌아온다
    // 
    InputStream is = conn.getInputStream();
    // , 
    Bitmap bm = BitmapFactory.decodeStream(is);
    
  • 그림을 ImageView의 디스플레이 내용으로 설정
    ImageView iv = (ImageView) findViewById(R.id.iv);
    iv.setImageBitmap(bm);
    
  • 권한 추가
  • 주 스레드는 막힐 수 없습니다

  • 안드로이드에서 메인 라인이 막히면 응용 프로그램이 ui인터페이스를 리셋할 수 없고 사용자의 조작에 응답할 수 없으며 사용자 체험이 매우 나쁘다
  • 주 스레드가 너무 오래 막히면 ANR 예외
  • 가 발생합니다.
  • ANR:Application Not Response;애플리케이션 응답 없음
  • 운영 스레드에 쓸 수 없는 시간 소모 작업
  • 네트워크 상호작용은 시간 소모 조작에 속하기 때문에 네트워크 속도가 느리면 코드가 막히기 때문에 네트워크 상호작용의 코드는 메인 라인에서 실행할 수 없다
  • 주 라인만 ui를 리셋할 수 있습니다

  • ui 리셋 코드는 주 라인에서만 실행되며 하위 라인에서만 실행되는 것은 아무런 효과가 없습니다
  • 하위 라인에서 ui를 리셋하려면 메시지 대기열 메커니즘을 사용합니다
  • 메시지 대기열
  • Looper는Message Queue에 메시지가 있는 것을 발견하면 메시지를 꺼내서Handler 대상에게 던진다.Handler는 자신의handle Message 방법을 사용해서 이 메시지를 처리한다
  • handleMessage 방법은 주 스레드
  • 에서 실행
  • 메인 스레드가 생성되면 메시지 대기열과 휠체어 대상이 생성되지만 메시지 프로세서 대상은 사용이 필요할 때 자체로 생성
    // 
    Handler handler = new Handler(){
        // looper, , , , 
        public void handleMessage(android.os.Message msg) {
    
        }
    };
    
  • 서브라인에서 메시지 대기열에 메시지 보내기
    // 
    Message msg = new Message();
    // obj , 
    msg.obj = bm;
    //what , , 
    msg.what = 1;
    // 
    handler.sendMessage(msg);
    
  • switch 문장을 통해 서로 다른 소식을 구분
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        // 1, 
        case 1:
            ImageView iv = (ImageView) findViewById(R.id.iv);
            Bitmap bm = (Bitmap) msg.obj;
            iv.setImageBitmap(bm);
            break;
        case 2:
            Toast.makeText(MainActivity.this, " ", 0).show();
            break;
        }       
    }
    
  • 캐시 이미지 추가 기능

  • 서버가 되돌아오는 흐름의 데이터를 읽고 파일 입력을 통해 로컬 파일
    //1. 
    InputStream is = conn.getInputStream();
    //2. , 
    
    FileOutputStream fos = new FileOutputStream(file);
    byte[] b = new byte[1024];
    int len = 0;
    while((len = is.read(b)) != -1){
        fos.write(b, 0, len);
    }
    
  • 에 흘려쓰기
  • bitmap 대상을 만드는 코드를
    Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
    
  • 로 변경
  • 매번 요청을 보내기 전에 캐시에 같은 이름의 그림이 있는지 확인하고 존재하면 캐시를 읽기
  • 소스 코드를 가져오는 사이트

  • code.google.com
  • github.com
  • github에서 smart-image-view
  • 검색
  • 소스 오픈 프로젝트 스마트-image-view
  • 다운로드
  • 사용자 정의 구성 요소를 사용할 때 탭 이름은 패키지 이름을 써야 한다
    <com.loopj.android.image.SmartImageView/>
    
  • SmartImageView 사용
    SmartImageView siv = (SmartImageView) findViewById(R.id.siv);
    siv.setImageUrl("http://192.168.1.102:8080/dd.jpg");
    
  • Html 소스 뷰어

  • GET 요청 보내기
    URL url = new URL(path);
    // 
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    // 
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    // , 
    if(conn.getResponseCode() == 200){
    
    }
    
  • 서버가 되돌아오는 흐름을 가져오고 흐름에서 html 원본을 읽는다
    byte[] b = new byte[1024];
    int len = 0;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    while((len = is.read(b)) != -1){
        // 
        bos.write(b, 0, len);
    }
    // 
    // utf-8
    text = new String(bos.toByteArray());
    
  • 무분별한 처리

  • 혼란이 발생한 것은 서버와 클라이언트 코드 테이블이 일치하지 않아서
    // 
    text = new String(bos.toByteArray(), "gb2312");
    
  • 데이터 제출


    GET 방식으로 데이터 전송

  • get 방식으로 제출한 데이터는 URL의 끝에 직접 연결
    final String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + name + "&pass=" + pass;
    
  • get 요청을 보내는데 코드는 이전과 같다
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setReadTimeout(5000);
    conn.setConnectTimeout(5000);
    if(conn.getResponseCode() == 200){
    
    }
    
  • 브라우저는 요청을 보낼 때 데이터를 URL로 인코딩하고 우리가 코드를 쓸 때도 중국어를 위한 URL 인코딩
    String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + URLEncoder.encode(name) + "&pass=" + pass;
    
  • POST 방식으로 데이터 전송

  • post 제출 데이터는 서버로 전송됨
  • 프로토콜 헤더에 두 개의 속성이 더 있습니다
  • Content-Type: 응용 프로그램/x-www-form-urlencoded, 제출한 데이터를 설명하는 mimetype
  • Content-Length: 32, 제출한 데이터의 길이
    // post 
    String data = "name=" + URLEncoder.encode(name) + "&pass=" + pass;
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setRequestProperty("Content-Length", data.length() + "");
    
  • 설명
  • post 요청을 열 수 있는 흐름 설정
    conn.setDoOutput(true);
    
  • 연결 대상의 출력 흐름을 가져오고 서버에 제출할 데이터를 흐름에 쓰기
    OutputStream os = conn.getOutputStream();
    os.write(data.getBytes());
    
  • 좋은 웹페이지 즐겨찾기