2013-10-31 6 views
0

asycTask의 doInBackground() 메소드에서 소켓을 작성하려고 할 때 android.os.NetworkOnMainThreadException이 발생할 수 있습니다. AsyncTask에서 NetworkOnMainThreadException을 생성 중입니다.

은 AsyncTask를의 코드입니다 :

package com.example.bulbcontrol2; 
import java.net.InetAddress; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.AsyncTask; 
import android.widget.TextView; 

public class AsyncConnection extends AsyncTask<Object, String, String> { 
    private TextView textV; 
    private Context context; 
    private String message; 
    private Device bulb; 

    public AsyncConnection(TextView textViewToUpdate,Context context) 
    { 
     this.textV = textViewToUpdate; 
     this.context = context; 
    } 

    @Override 
    protected String doInBackground(Object... params) { 

     bulb = new Device((InetAddress) params[0],(Integer) params[1]); 

     BroadcastReceiver receiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       if (intent.getAction().equals("open_connection")) 
       { 
        System.out.println(bulb.connectToHW()); 
        message = "Connected"; 
        System.out.println(bulb.dataTransferHW("hello")); 
        textV.setText(message);          
       } 
       if (intent.getAction().equals("close_connection")) 
       { 
        message = "Disconnected"; 
        System.out.println(bulb.dataTransferHW("bye")); 
        bulb.closeConexHW(); 
       } 
      } 
     }; 

     IntentFilter filter = new IntentFilter("open_connection"); 
     context.registerReceiver(receiver, filter); 
     filter.addAction("close_connection"); 
     context.registerReceiver(receiver, filter); 

     return message; 
    } 
/* protected void onProgressUpdate(String... progress) { 
     //textV.setText(progress[0]); 
    }*/ 

} 

그리고 이것은 UIThread의 코드입니다 :

package com.example.bulbcontrol2; 

import java.net.InetAddress; 
import java.net.UnknownHostException; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.CompoundButton; 
import android.widget.TextView; 
import android.widget.ToggleButton; 

public class MainActivity extends Activity 
{ 
    Intent broadcastIntent = new Intent(); 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     bulbActions(); 
    } 

    public void bulbActions() 
    { 
     final ToggleButton buttonBulb = (ToggleButton) findViewById(R.id.ToggleBulb); 
     final ToggleButton buttonLDR = (ToggleButton) findViewById(R.id.ToggleLDRValues); 
     final TextView txtLDR = (TextView) findViewById(R.id.TxtLDRValues); 
     byte [] hostBytes = new byte[] {(byte)192,(byte)168,(byte)0,(byte)12}; 
     int port = 5006; 
     InetAddress host = null; 

     try 
     { 
      host = InetAddress.getByAddress(hostBytes); 
     } 
     catch (UnknownHostException e) 
     { 
      System.out.println("\nError with server address"); 
      e.printStackTrace(); 
     } 
     new AsyncConnection((TextView)findViewById(R.id.TxtLDRValues),this.getApplicationContext()).execute(host,port);  

     buttonBulb.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View arg0) 
      {    
       if (buttonBulb.isChecked()) 
       { 
        System.out.println("Pulsado"); 
        broadcastIntent.setAction("open_connection"); 
        MainActivity.this.sendBroadcast(broadcastIntent); 
       } 
       else 
       { 
        System.out.println("NO Pulsado"); 
        broadcastIntent.setAction("close_connection"); 
        MainActivity.this.sendBroadcast(broadcastIntent); 
       } 
      } 
     }); 
    } 
} 
+1

'host = InetAddress.getByAddress (hostBytes);'이 작업은 네트워크 작업입니까 – Raghunandan

+1

네트워크 작업의 정확한 위치는 logcat의 스택 추적을 확인하십시오. Raghunandan의 관찰은 좋은 후보이다. – laalto

+0

AsyncTask를 사용하는 방법은 UI 스레드에 대한 호출을 어떻게 든 이동해야합니다. IntentService가 귀하의 유스 케이스에 훨씬 더 잘 어울릴 것이라고 믿습니다. 아마도 IntentServices는 '일회성'배경 작업이므로 제어가 필요하기 때문에 서비스 만 필요할 수도 있습니다. – cYrixmorten

답변

0

당신의 doInBackground 그냥 브로드 캐스트 리시버를 정의하고이를 등록한다. onReceive 내의 모든 코드는 시스템이 onClick을 따라 호출 할 때 주 스레드에서 실행됩니다.

방금 ​​단추로 트리거하는 경우 BroadcastReceiver가 필요한 이유를 알지 못합니다. 대신 doInBackground에서 직접 네트워크 작업을 수행 한 다음 실제로 onClick 내에서 AsyncTask를 시작할 수 있습니다.

BroadcastReceiver가 필요한 경우에는 onReceive에서 서비스를 시작하고 서비스의 모든 네트워크 작업을 수행해야합니다. API11 이후에도 수신기에서 goAsync()를 사용하여 here과 같이 설명하고 스레드를 시작할 수 있습니다.