0

如果我从我的 asycTask 的 doInBackground() 方法中尝试创建一个调用bulb.connectToHW() 的套接字,我怎么可能得到 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);
                }
            }
        }); 
    }
}
4

1 回答 1

0

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

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

在您确实需要 BroadcastReceiver 的情况下,您想做的是从 onReceive 启动服务并完成服务中的所有网络工作。在 API11 之后,您还可以按照此处所述在接收器中使用 goAsync()并启动线程。

于 2014-01-22T12:03:53.297 回答