获取NetworkOnMainThreadException在AsyncTask中创建套接字

时间:2013-10-31 12:42:09

标签: android sockets android-asynctask networkonmainthread

当我尝试创建一个调用bulb.connectToHW()的套接字时,如果我从asycTask的doInBackground()方法中执行它,我怎么可能得到android.os.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 个答案:

答案 0 :(得分:0)

你的doInBackground只是定义一个BroadcastReceiver并注册它。当系统在onClick之后调用它时,onReceive中的所有代码都将在主线程中运行。

如果你只是从一个按钮触发它,我不知道为什么你需要一个BroadcastReceiver。 相反,您可以直接在doInBackground上执行网络操作,然后实际启动onClick内的AsyncTask。

在一个案例中你需要一个BroadcastReceiver你想要做的是从onReceive启动一个服务并在服务中完成所有的网络工作。 在API11之后,您还可以按照here所述在接收器中使用goAsync()并启动一个线程。