마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

xml 파싱 도중 URL 오류 납니다.

0 추천
case R.id.btn:
URL url = null;
try {
url = new URL("서버IP/xmlTest/insert.php?"+"id="+URLEncoder.encode("id_kang","UTF-8")+"&password="+URLEncoder.encode("password","UTF-8"));
} catch (MalformedURLException e) {
 
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
 
e.printStackTrace();
}
        url.openStream();
 
break;
서버에 있는 PHP에 id랑 password를 입력해서 보내려고 하는데 계속 오류가 뜨네요
위에 있는 부분은 버튼을 클릭했을때 구동되는 부분입니다.
강문성 (130 포인트) 님이 2013년 7월 23일 질문

1개의 답변

+1 추천

흠~~~!

네트웍작업등 시간이 오래 걸릴수 있는 작업은 메인쓰레드에서 할 수 없습니다.

멀티 쓰레드를 이용하시던 asynctask를 이용하세요.

그리고 매번 이렇게 쉽게 답을 얻으시는것도 버릇이 됩니다.

분명히 로그에 

android.os.NetworkOnMainThreadException
 
라고 친절히 찍혔을 텐데....
 
머 다 방법이 다르겠지만....
 
스키나 보드도 넘어지는 법을 먼저 배우듯이...
 
개발도 개발하는 방법을 아는 것보다 발생한 이슈를 해결하는 최소한의 방법은 습득하는게 먼저 라고 봅니다.
 
 
 
ThisPlus (46,920 포인트) 님이 2013년 7월 23일 답변
댓글 감사합니다.
아 그런데 제가 스레드로 해봤는데..
start()로 시작하면 url이 php문에 인자 값들이 들어가면서 결과가 잘 나오는데   run() 메소드로 재실행 하니깐 url을 타고 들어갈 인자 값들이 들어 가질 않습니다.
run과 start 의 차이는 어느 정도는 알겠는데
start에서도 run을 실행하는 것과
start를 실행하고 개발자가 run을 다시 실행하는 것의 차이가 있나요?

public class MainActivity extends Activity {
    int i=0;
    EditText id_input, password_input;
    TextView check;
    Button checkBtn, btn;
    BackThread xmlThread;
    String ret="";
    ArrayList<String> array_id;
    ArrayAdapter<String> adapter;
    ListView id_list;
    ListView list;
    Thread t1;
    private static final String SERVER_ADDRESS ="http://서버아이피";
    String uri="http://서버아이피/xmlTest/result.xml"; //원하는 링크 접속
    String tagname, content; //xml의 태그와 내용을 담기 위한 변수
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        id_input=(EditText)findViewById(R.id.id_input);
        password_input=(EditText)findViewById(R.id.password_input);
        check=(TextView)findViewById(R.id.check);
        btn=(Button)findViewById(R.id.btn);
        checkBtn=(Button)findViewById(R.id.checkBtn);
        clickListener click= new clickListener();
        checkBtn.setOnClickListener(click);
        btn.setOnClickListener(click);
        array_id=new ArrayList<String>();
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,array_id);
        list=(ListView)findViewById(R.id.list);
        list.setAdapter(adapter);
        xmlThread= new BackThread();
        t1 = new Thread(xmlThread);
        t1.start();
    
    }
     Handler xmlHandler=new Handler(){
            public void handleMessage(Message msg){
                if(msg.what==0){
                   
                    adapter.notifyDataSetChanged();
                   
                    //check.setText(array_id.get(0));
                   
                }
           
                //id_input.setText("");
                //password_input.setText("");
               
            }
        };
    class clickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            switch(v.getId()){
            case R.id.checkBtn:
                //xmlThread.setFlag(true);
                //if(id_input.getText().toString().equals("")){return;}
               
               
                t1.run();
                //t1.start();
                //xmlThread.start();
                break;
            case R.id.btn:
                URL url = null;
                try {
                    url = new URL("서버아이피/xmlTest/insert.php?"+"id="+URLEncoder.encode("1","UTF-8")+"&password="+URLEncoder.encode("12345","UTF-8"));
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                 
                break;
            }
           
        }
       
    }

    class BackThread implements Runnable {
       
        public void run() {
           
            try{
           
               
                String id=id_input.getText().toString();
                String password=password_input.getText().toString();
                String rss = SERVER_ADDRESS + "/xmlTest/";
                String tagname="";
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); //xmlPullparser를 위한 준비과정.
                factory.setNamespaceAware(true); //xml의 네임페이스 허용
                XmlPullParser xpp = factory.newPullParser();
            //======================================== run()으로 하면 안되는 부분.
                 URL url = new URL(SERVER_ADDRESS+"/xmlTest/insert.php?"+"id="+URLEncoder.encode(id,"UTF-8")+"&password="+URLEncoder.encode(password,"UTF-8"));
                 //======================================== run()으로 하면 안되는 부분.
                url.openStream();
                 URLConnection urlConnection = null;
                urlConnection = url.openConnection();
                check.setText(SERVER_ADDRESS);
                URL server = new URL(rss + "insert.xml");
               
                InputStream is = server.openStream();
                xpp.setInput(is, "UTF-8");
               
                int eventType = xpp.getEventType(); //이벤트 타입 얻어오기 예르들어 <start> 인지 </start> 인지 구분하기 위한.
               
                while(eventType != XmlPullParser.END_DOCUMENT) {
                    if(eventType == XmlPullParser.START_TAG) {
                       
                            tagname=xpp.getName();
                       
                    }
                    else if(eventType==XmlPullParser.TEXT){
                        array_id.add(xpp.getText());
                            if(tagname.equals("id")){
                                array_id.add(xpp.getText());
                                ret=xpp.getText();     //바뀐 부분...
   
                            }
                           
                       
                    }else if(eventType==XmlPullParser.END_TAG){
                        //바뀐 부분...
                        tagname=xpp.getName();
                        if(tagname.equals("id")){
                            array_id.add(ret);
                        }
                       
                    }
                    eventType = xpp.next();
                }

               
            }// try문 끝
            catch(Exception e){
                e.getMessage();
           
            } //catch문 끝
            finally{
           
            xmlHandler.sendEmptyMessage(0);
            }
           
        }

    }
run() 으로 돌리면 새로 만든 스레드로 돌리는게 아니라
메인스레드로 돌리는 것이랑 같습니다.
메인에서 스레드 없이 그냥 run() 함수 만든거랑 동일하다는 것입니다.
고로 인자값이 안들어가는 정도가 아니라  url.openStream(); 부분에서
먼저번이랑 같은 에러가 날텐데요?
오류가 발생하지 않아서 조금 많이 해매고 있었어요..
그럼 저런 방식으로 할려면 안되는 건지...
스레드 죽이려고 하니깐 오류 뜨고, while 쓰려니깐 안되고,,
interrupt함수나 resume 여러 함수도 쓰려고 해도 안되서..
지금은 zoeas님 글 중에서 본 Runnable( 작동기능).start() 해서
잘 작동 되서 쓰고는 있습니다. 하지만 위에 같은 상황에서는
어떻게 해야 하는지..
...